All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.granite.ui.components.LayoutBuilder Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.granite.ui.components;

import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;

/**
 * A builder to create a layout. A layout is a configuration map consisting a
 * set of properties. A layout at very least requires a {@code name} property.
 */
@SuppressWarnings("deprecation")
public class LayoutBuilder {
    private static final String NAME = "name";

    private JSONObject result;
    private String resourceType;

    @Nonnull
    private ValueMap vm;

    /**
     * Builds a layout from the given config. The actual layout resource is
     * retrieved based on {@link Config#LAYOUT} path. This method doesn't set
     * default resource type of layout, use {@link #from(Config, String)} or
     * {@link ComponentHelper#getLayout()} instead.
     *
     * @param config
     *            the config
     * @return the layout builder
     */
    @Nonnull
    public static LayoutBuilder from(@Nonnull Config config) {
        return LayoutBuilder.from(config.getChild(Config.LAYOUT));
    }

    /**
     * Builds a layout from the given config. The actual layout resource is
     * retrieved based on {@link Config#LAYOUT} path. The given defaultResourceType
     * will be used when sling:resourceType property of the resource is not set.
     *
     * @param config
     *            the config
     * @param defaultResourceType
     *            the default resource type
     * @return the layout builder
     */
    @Nonnull
    public static LayoutBuilder from(@Nonnull Config config, @Nonnull String defaultResourceType) {
        return LayoutBuilder.from(config.getChild(Config.LAYOUT), defaultResourceType);
    }

    /**
     * Builds a layout from the given resource. This method doesn't set default
     * resource type of layout, use {@link #from(Resource, String)} or
     * {@link ComponentHelper#getLayout()} instead.
     *
     * @param resource
     *            the resource
     * @return the layout builder
     */
    @Nonnull
    public static LayoutBuilder from(@CheckForNull Resource resource) {
        return from(resource, null);
    }

    /**
     * Builds a layout from the given resource. The given defaultResourceType will
     * be used when sling:resourceType property of the resource is not set.
     *
     * @param resource
     *            the resource
     * @param defaultResourceType
     *            the default resource type
     * @return the layout builder
     */
    @SuppressWarnings("null")
    @Nonnull
    public static LayoutBuilder from(@CheckForNull Resource resource, @CheckForNull String defaultResourceType) {
        LayoutBuilder b = new LayoutBuilder(resource);

        if (defaultResourceType == null) {
            b.setResourceType(b.vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class));
        } else {
            b.setResourceType(b.vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, defaultResourceType));
        }

        return b;
    }

    public LayoutBuilder() {
        this(null);
    }

    @SuppressWarnings("null")
    public LayoutBuilder(@CheckForNull Resource resource) {
        this.vm = resource != null ? resource.getValueMap() : ValueMap.EMPTY;
    }

    private void init() {
        if (result != null) {
            return;
        }

        result = new JSONObject();
        add(vm);
    }

    /**
     * {@code true} if this layout has name. {@code false} otherwise.
     *
     * @return {@code true} if this layout has a name, {@code false} otherwise
     */
    public boolean hasName() {
        init();
        return result.has(NAME);
    }

    /**
     * Returns the name of this layout.
     *
     * @return returns the name of this layout
     */
    @CheckForNull
    public String getName() {
        init();
        return result.optString(NAME, null);
    }

    /**
     * Sets the name of this layout.
     *
     * @param name
     *            the name to set
     */
    public void setName(@CheckForNull String name) {
        try {
            init();
            result.put(NAME, name);
        } catch (JSONException impossible) {
            throw new RuntimeException(impossible);
        }
    }

    /**
     * Returns the resource type of this layout. This will be used to point to the
     * renderer of the layout using standard Sling mechanism.
     *
     * @return the resource type as a string
     */
    @CheckForNull
    public String getResourceType() {
        return resourceType;
    }

    /**
     * Sets the resource type of this layout.
     *
     * @param resourceType
     *            the resource type to set
     */
    public void setResourceType(@CheckForNull String resourceType) {
        this.resourceType = resourceType;
    }

    /**
     * Adds the given key-value pair of property to this layout.
     *
     * @param key
     *            the property key
     * @param value
     *            the property value
     */
    public void add(@Nonnull String key, @CheckForNull Object value) {
        try {
            init();
            result.accumulate(key, value);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Adds a map of properties to this layout. Entry with key having a namespace
     * (e.g. jcr:primaryType) will be excluded.
     *
     * @param data
     *            the map of properties to add
     */
    public void add(@Nonnull Map data) {
        try {
            init();
            for (Entry e : data.entrySet()) {
                String key = e.getKey();

                if (key.indexOf(":") >= 0) {
                    continue;
                }

                result.accumulate(key, e.getValue());
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Returns this layout as JSON.
     *
     * @return the layout as JSON
     */
    @SuppressWarnings("null")
    @Nonnull
    public JSONObject toJSON() {
        init();
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy