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;
}
}