com.google.template.soy.data.internal.AugmentedSoyMapData.java Source code

Java tutorial

Introduction

Here is the source code for com.google.template.soy.data.internal.AugmentedSoyMapData.java

Source

/*
 * Copyright 2008 Google Inc.
 *
 * 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 com.google.template.soy.data.internal;

import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.google.template.soy.data.SoyData;
import com.google.template.soy.data.SoyDataException;
import com.google.template.soy.data.SoyListData;
import com.google.template.soy.data.SoyMapData;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Augmented map data combining a base map data object with some additional data that may hide some
 * of the base map data (if they have the same keys).
 *
 * <p> Important: Do not use outside of Soy code (treat as superpackage-private).
 *
 * @author Kai Huang
 */
public class AugmentedSoyMapData extends SoyMapData {

    /** The base map data object. */
    private final SoyMapData baseData;

    /**
     * @param baseData The base map data object.
     */
    public AugmentedSoyMapData(SoyMapData baseData) {
        Preconditions.checkNotNull(baseData);
        this.baseData = baseData;
    }

    @Override
    public Map<String, SoyData> asMap() {

        SoyMapData combinedMapData = new SoyMapData();
        addMapDataHelper(combinedMapData, "", baseData.asMap());
        addMapDataHelper(combinedMapData, "", super.asMap());
        return Collections.unmodifiableMap(combinedMapData.asMap());
    }

    /**
     * Private helper for {@code asMap()} to add a map (or submap) to the combined map data.
     * @param combinedMapData The combined map data that we're building.
     * @param keyPrefix The key prefix if adding a submap (or empty string if adding one of the
     *     top-level maps: the base data or the augmented data).
     * @param map The map of data to add.
     */
    private static void addMapDataHelper(SoyMapData combinedMapData, String keyPrefix, Map<String, SoyData> map) {

        for (Map.Entry<String, SoyData> entry : map.entrySet()) {
            String key = entry.getKey();
            SoyData value = entry.getValue();
            if (value instanceof SoyMapData) {
                addMapDataHelper(combinedMapData, keyPrefix + key + ".", ((SoyMapData) value).asMap());
            } else if (value instanceof SoyListData) {
                addListDataHelper(combinedMapData, keyPrefix + key + ".", ((SoyListData) value).asList());
            } else {
                combinedMapData.put(keyPrefix + key, value);
            }
        }
    }

    /**
     * Private helper for {@code asMap()} to add a sublist to the combined map data.
     * @param combinedMapData The combined map data that we're building.
     * @param keyPrefix The key prefix for this sublist.
     * @param list The list of data to add.
     */
    private static void addListDataHelper(SoyMapData combinedMapData, String keyPrefix, List<SoyData> list) {

        for (int i = 0; i < list.size(); ++i) {
            SoyData el = list.get(i);
            if (el instanceof SoyMapData) {
                addMapDataHelper(combinedMapData, keyPrefix + i + ".", ((SoyMapData) el).asMap());
            } else if (el instanceof SoyListData) {
                addListDataHelper(combinedMapData, keyPrefix + i + ".", ((SoyListData) el).asList());
            } else {
                combinedMapData.put(keyPrefix + i, el);
            }
        }
    }

    @Override
    public Set<String> getKeys() {
        return Collections.unmodifiableSet(Sets.union(super.getKeys(), baseData.getKeys()));
    }

    @Override
    public String toString() {
        return toStringHelper(asMap());
    }

    @Override
    public boolean toBoolean() {
        return true;
    }

    @Override
    public void put(String keyStr, SoyData value) {
        if (keyStr.indexOf('.') >= 0) {
            throw new SoyDataException(
                    "Attempted to put multi-part key string into AugmentedSoyMapData. Please ensure that"
                            + " all of your 'param' commands only use top-level keys.");
        }
        super.putSingle(keyStr, value);
    }

    // Note: No need to override putSingle since it would do same thing as super method.

    /**
     * Removal of data from AugmentedSoyMapData is not well defined, so it's prohibited.
     */
    @Override
    public void remove(String keyStr) {
        throw new UnsupportedOperationException();
    }

    /**
     * Removal of data from AugmentedSoyMapData is not well defined, so it's prohibited.
     */
    @Override
    public void removeSingle(String key) {
        throw new UnsupportedOperationException();
    }

    @Override
    public SoyData getSingle(String key) {

        SoyData value = super.getSingle(key);
        if (value != null) {
            return value;
        }
        return baseData.getSingle(key);
    }

}