biz.turnonline.ecosystem.origin.frontend.content.subscription.BaseRawContent.java Source code

Java tutorial

Introduction

Here is the source code for biz.turnonline.ecosystem.origin.frontend.content.subscription.BaseRawContent.java

Source

/*
 * Copyright 2018 Comvai, s.r.o.
 *
 * 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 biz.turnonline.ecosystem.origin.frontend.content.subscription;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.services.pubsub.model.PubsubMessage;
import com.google.common.base.Splitter;
import com.googlecode.objectify.annotation.Id;
import org.apache.commons.codec.binary.Base64;

import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Locale;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * There is a limit on the unindexed content, data cannot exceed size 1,048,487 bytes.
 * https://cloud.google.com/datastore/docs/concepts/limits
 *
 * @author <a href="mailto:medvegy@turnonline.biz">Aurel Medvegy</a>
 */
abstract class BaseRawContent<T> implements Serializable {
    private static final long serialVersionUID = -4455679222818613582L;

    private final Class<T> type;

    @Id
    private String name;

    private String content;

    /**
     * Constructor.
     *
     * @param type the target type of the serialized content
     */
    BaseRawContent(Class<T> type) {
        this.type = type;
    }

    /**
     * Constructor.
     *
     * @param name the unique name of the content
     * @param type the target type of the serialized content
     */
    BaseRawContent(String name, Class<T> type) {
        this.name = checkNotNull(name, "Content's unique name must be provided.");
        this.type = checkNotNull(type, "Content's type must be provided.");
    }

    /**
     * Deserialize JSON content from data (either encoded in Base64 form or regular string)
     * and returns the target instance populated with values from the JSON data.
     *
     * @param mapper the JSON mapper
     * @return the concrete instance populated with values from the JSON data
     * @throws IOException if deserialization fails
     */
    public T convert(ObjectMapper mapper) throws IOException {
        if (content == null) {
            return null;
        }

        String decoded;
        if (Base64.isBase64(content.getBytes())) {
            decoded = new String(new PubsubMessage().setData(content).decodeData(), Charset.forName("UTF-8"));
        } else {
            decoded = content;
        }
        return mapper.readValue(decoded, type);
    }

    public String getName() {
        return name;
    }

    /**
     * Sets the content.
     * The string is allowed to be either encoded in Base64 form or regular string.
     *
     * @param content the content to be set
     */
    public void setContent(String content) {
        this.content = checkNotNull(content);
    }

    /**
     * Returns the length of the content.
     *
     * @return the length of the content
     */
    public int length() {
        if (content == null) {
            return 0;
        }
        return content.length();
    }

    /**
     * Extracts the owner of the content in form of the full domain taken from the content name.
     *
     * @return the domain as owner of the content
     */
    public String getOwnerFromName() {
        checkNotNull(this.name, "Content name cannot be null");
        List<String> strings = Splitter.on("@").omitEmptyStrings().splitToList(this.name);
        return strings.isEmpty() ? null : strings.get(strings.size() - 1);
    }

    /**
     * Extracts the locale taken from the content name.
     * It's expected content name will always start with locale prefix (received or default).
     *
     * @return the locale
     */
    public Locale getLocaleFromName() {
        checkNotNull(this.name, "Content name cannot be null");
        List<String> strings = Splitter.on("::").omitEmptyStrings().splitToList(this.name);

        Locale locale;
        if (strings.size() >= 2) {
            // only single locale separator found
            locale = new Locale(strings.get(0));
        } else {
            // there is no locale separator, this should not happen with valid full content name
            locale = null;
        }

        return locale;
    }
}