org.reficio.cougar.core.FrameBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.reficio.cougar.core.FrameBuilder.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.reficio.cougar.core;

import org.apache.commons.lang.StringUtils;
import org.reficio.cougar.StompInvalidHeaderException;
import org.reficio.cougar.domain.*;

import java.util.*;

import static org.reficio.cougar.domain.HeaderType.*;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * User: Tom Bujok (tom.bujok@reficio.org)
 * Date: 2010-11-22
 * Time: 7:54 PM
 * <p/>
 * Reficio (TM) - Reestablish your software!
 * http://www.reficio.org
 */
public class FrameBuilder implements Cloneable {

    protected String command;
    protected Map<String, Header> headers;
    protected String payload;
    private boolean headersValidationEnabled;
    private Set<String> frozenHeaders;

    protected FrameBuilder(Command command, Map<String, Header> headers, String payload) {
        this.command = checkNotNull(command, "command cannot be null").getName();
        this.headers = checkNotNull(headers, "headers cannot be null");
        this.payload = checkNotNull(payload, "payload cannot be null");
        this.headersValidationEnabled = true;
    }

    public FrameBuilder(Command command) {
        this(command, true);
    }

    public FrameBuilder(Command command, boolean headersValidationEnabled) {
        this(checkNotNull(command, "command cannot be null").getName(), headersValidationEnabled);
    }

    public FrameBuilder(String commandName) {
        this(commandName, true);
    }

    public FrameBuilder(String commandName, boolean headersValidationEnabled) {
        this.command = checkNotNull(commandName, "commandName cannot be null");
        this.headers = new TreeMap<String, Header>();
        this.headersValidationEnabled = headersValidationEnabled;
    }

    public Command getCommand() {
        return Command.getCommand(command);
    }

    public String getCommandName() {
        return command;
    }

    // ----------------------------------------------------------------------------------
    // Header mutators
    // ----------------------------------------------------------------------------------
    private void addHeaderByType(HeaderType type, String value) {
        checkNotNull(type, "type cannot be null");
        isHeaderAllowed(type);
        addHeaderByName(type.getName(), value);
    }

    private void addHeaderByName(String name, String value) {
        checkNotNull(name, "name cannot be null");
        if (value == null) {
            this.headers.remove(name);
        } else {
            if (isFrozen()) {
                if (frozenHeaders.contains(name)) {
                    throw new StompInvalidHeaderException(String
                            .format("Header [%s] can't be used in the decorator, it is set by the API", name));
                }
            }
            this.headers.put(name, Header.createHeader(name, value));
        }
    }

    // ----------------------------------------------------------------------------------
    // Validation handlers
    // ----------------------------------------------------------------------------------
    private boolean isHeadersValidationEnabled() {
        return this.headersValidationEnabled;
    }

    private void isHeaderAllowed(HeaderType type) {
        if (isHeadersValidationEnabled()) {
            if (type.isAllowed((Frame) this) == false) {
                throw new StompInvalidHeaderException(
                        String.format("Header [%s] is not allowed in frame [%s]", type.name(), command));
            }
        }
    }

    private void validateEnumValue(Class enumClass, String value) throws StompInvalidHeaderException {
        try {
            Enum.valueOf(enumClass, value);
        } catch (IllegalArgumentException ex) {
            throw new StompInvalidHeaderException(
                    String.format("Value [%s] invalid for enum type [%s]", value, enumClass));
        }
    }

    // ----------------------------------------------------------------------------------
    // Freeze handlers - if the header is frozen there is no possibility to change any properties
    // ----------------------------------------------------------------------------------
    public void freeze() {
        if (isFrozen() == false) {
            this.frozenHeaders = new HashSet(this.headers.keySet());
        }
    }

    public boolean isFrozen() {
        return this.frozenHeaders != null;
    }

    // ----------------------------------------------------------------------------------
    // Clone handlers
    // ----------------------------------------------------------------------------------
    @Override
    public Object clone() throws CloneNotSupportedException {
        FrameBuilder clone = (FrameBuilder) super.clone();
        clone.frozenHeaders = null;
        clone.headers = new TreeMap<String, Header>(headers);
        return clone;
    }

    // ----------------------------------------------------------------------------------
    // Generic header accessors
    // ----------------------------------------------------------------------------------
    public Header getHeader(HeaderType type) {
        checkNotNull(type, "type cannot be null");
        return getHeader(type.getName());
    }

    public Header getHeader(String name) {
        checkNotNull(name, "name cannot be null");
        return this.headers.get(name);
    }

    public String getHeaderValue(HeaderType type) {
        checkNotNull(type, "type cannot be null");
        Header header = getHeader(type.getName());
        return (header != null) ? header.getValue() : null;
    }

    public String getHeaderValue(String name) {
        checkNotNull(name, "name cannot be null");
        Header header = getHeader(name);
        return (header != null) ? header.getValue() : null;
    }

    public List<Header> getHeaders() {
        // headers are immutable, so no problem
        return new ArrayList<Header>(headers.values());
    }

    // ----------------------------------------------------------------------------------
    // Tweaked builder setters and getters; builder pattern -> invocations can be chained
    // ----------------------------------------------------------------------------------
    public FrameBuilder payload(String payload) {
        return payload(payload, false);
    }

    public FrameBuilder payload(String payload, boolean disableContentLenghtHeader) {
        this.payload = payload;
        if (disableContentLenghtHeader == false) {
            if (CONTENT_LENGTH.isAllowed((Frame) this)) {
                if (payload != null) {
                    contentLength(Integer.valueOf(payload.length()).toString());
                } else {
                    contentLength(null);
                }
            }
        }
        return this;
    }

    public String payload() {
        return this.payload;
    }

    public FrameBuilder login(String value) {
        addHeaderByType(LOGIN, value);
        return this;
    }

    public String login() {
        return getHeaderValue(LOGIN);
    }

    public FrameBuilder encoding(String value) {
        addHeaderByType(ENCODING, value);
        return this;
    }

    public String encoding() {
        return getHeaderValue(ENCODING);
    }

    public FrameBuilder subscription(String value) {
        addHeaderByType(SUBSCRIPTION, value);
        return this;
    }

    public String subscription() {
        return getHeaderValue(SUBSCRIPTION);
    }

    public FrameBuilder passcode(String value) {
        addHeaderByType(PASS_CODE, value);
        return this;
    }

    public String passcode() {
        return getHeaderValue(PASS_CODE);
    }

    public FrameBuilder session(String value) {
        addHeaderByType(SESSION, value);
        return this;
    }

    public String session() {
        return getHeaderValue(SESSION);
    }

    public FrameBuilder destination(String value) {
        addHeaderByType(DESTINATION, value);
        return this;
    }

    public String destination() {
        return getHeaderValue(DESTINATION);
    }

    public FrameBuilder ack(Ack ack) {
        addHeaderByType(ACK, ack.name().toLowerCase().replace("_", "-"));
        return this;
    }

    public Ack ack() {
        String value = getHeaderValue(ACK);
        if (StringUtils.isNotBlank(value)) {
            validateEnumValue(Ack.class, value.toUpperCase());
            return Enum.valueOf(Ack.class, value.toUpperCase());
        } else {
            return null;
        }
    }

    public FrameBuilder transaction(String value) {
        addHeaderByType(TRANSACTION, value);
        return this;
    }

    public String transaction() {
        return getHeaderValue(TRANSACTION);
    }

    public FrameBuilder receipt(String value) {
        addHeaderByType(RECEIPT, value);
        return this;
    }

    public String receipt() {
        return getHeaderValue(RECEIPT);
    }

    public FrameBuilder errorMessageContent(String value) {
        addHeaderByType(ERROR_MESSAGE_CONTENT, value);
        return this;
    }

    public String errorMessageContent() {
        return getHeaderValue(ERROR_MESSAGE_CONTENT);
    }

    private FrameBuilder contentLength(String value) {
        addHeaderByType(CONTENT_LENGTH, value);
        return this;
    }

    public String contentLength() {
        return getHeaderValue(CONTENT_LENGTH);
    }

    public FrameBuilder subscriptionId(String value) {
        addHeaderByType(SUBSCRIPTION_ID, value);
        return this;
    }

    public String receiptId() {
        return getHeaderValue(RECEIPT_ID);
    }

    public FrameBuilder receiptId(String value) {
        addHeaderByType(RECEIPT_ID, value);
        return this;
    }

    public String messageId() {
        return getHeaderValue(MESSAGE_ID);
    }

    public FrameBuilder messageId(String value) {
        addHeaderByType(MESSAGE_ID, value);
        return this;
    }

    public String subscriptionId() {
        return getHeaderValue(SUBSCRIPTION_ID);
    }

    public FrameBuilder selector(String value) {
        addHeaderByType(SELECTOR, value);
        return this;
    }

    public String selector() {
        return getHeaderValue(SELECTOR);
    }

    public FrameBuilder custom(String name, String value) {
        HeaderType type = getInstance(name);
        if (type != null) {
            // isHeaderAllowed enum value
            if (type.equals(ACK)) {
                validateEnumValue(Ack.class, value);
            } else if (type.equals(CONTENT_LENGTH)) {
                throw new StompInvalidHeaderException(String.format(
                        "Header [%s] must not be set manually. It is set automatically while setting the payload.",
                        CONTENT_LENGTH.name()));
            }
            isHeaderAllowed(type);
            addHeaderByType(type, value);
        } else {
            addHeaderByName(name, value);
        }
        return this;
    }

    public String custom(String name) {
        return getHeaderValue(name);
    }

}