/**
* 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 org.brixcms.plugin.site.page;
import org.brixcms.Brix;
import org.brixcms.exception.NodeNotFoundException;
import org.brixcms.jcr.api.JcrNode;
import org.brixcms.jcr.api.JcrPropertyIterator;
import org.brixcms.jcr.api.JcrSession;
import org.brixcms.jcr.wrapper.BrixFileNode;
import org.brixcms.jcr.wrapper.BrixNode;
import org.brixcms.markup.tag.Item;
import org.brixcms.markup.variable.VariableKeyProvider;
import org.brixcms.markup.variable.VariableTransformer;
import org.brixcms.markup.variable.VariableValueProvider;
import org.brixcms.plugin.site.SitePlugin;
import org.brixcms.plugin.site.page.tile.TileContainerFacet;
import org.brixcms.plugin.site.page.tile.TileTag;
import javax.jcr.Node;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class AbstractContainer extends BrixFileNode
implements
VariableValueProvider,
VariableKeyProvider {
/**
* Name of markup attribute used to identify tile id inside brix:tile tag
*/
public static final String MARKUP_TILE_ID = "id";
private static final String VARIABLES_NODE_NAME = Brix.NS_PREFIX + "variables";
private final TileContainerFacet tileManager;
public AbstractContainer(Node delegate, JcrSession session) {
super(delegate, session);
tileManager = new TileContainerFacet(this);
}
/**
* Returns collection of possible variable keys for this node.
*/
public Collection<String> getVariableKeys() {
Set<String> keys = new HashSet<String>();
PageMarkupSource source = new PageMarkupSource(this);
VariableTransformer transfomer = new VariableTransformer(source, this);
Item i = transfomer.nextMarkupItem();
while (i != null) {
if (i instanceof VariableKeyProvider) {
Collection<String> k = ((VariableKeyProvider) i).getVariableKeys();
if (k != null) {
keys.addAll(k);
}
}
i = transfomer.nextMarkupItem();
}
keys.addAll(SitePlugin.get().getGlobalVariableKeys(getSession()));
return keys;
}
public String getVariableValue(String key) {
return getVariableValue(key, true);
}
public AbstractSitePagePlugin getNodePlugin() {
return (AbstractSitePagePlugin) SitePlugin.get().getNodePluginForNode(this);
}
@Override
public Protocol getRequiredProtocol() {
// requiring SSL takes precedence
if (requiresSSL()) {
return Protocol.HTTPS;
} else if (requiresNonSSL()) {
return Protocol.HTTP;
} else {
return Protocol.PRESERVE_CURRENT;
}
}
public boolean requiresSSL() {
Boolean requiresSSL = isRequiresSSL();
return (requiresSSL != null && requiresSSL.booleanValue()) || tileManager.anyTileRequiresSSL() || (getTemplate() != null && getTemplate().requiresSSL());
}
public Boolean isRequiresSSL() {
if (hasProperty(Properties.REQUIRES_SSL)) {
return getProperty(Properties.REQUIRES_SSL).getBoolean();
} else {
return null;
}
}
public boolean requiresNonSSL() {
// ignore tiles assuming that tiles which don't require SSL are equivalent to Protocol.PRESERVE_CURRENT
// in future could add method: Protocol getRequiredProtocol() to Tile
Boolean requiresSSL = isRequiresSSL();
return (requiresSSL != null && !requiresSSL.booleanValue()) || (getTemplate() != null && getTemplate().requiresNonSSL());
}
public List<String> getSavedVariableKeys() {
if (hasNode(VARIABLES_NODE_NAME)) {
JcrNode node = getNode(VARIABLES_NODE_NAME);
List<String> result = new ArrayList<String>();
JcrPropertyIterator i = node.getProperties();
while (i.hasNext()) {
String name = i.nextProperty().getName();
// filter out jcr: properties (or other possible brix properties)
if (!name.contains(":")) {
result.add(name);
}
}
return result;
} else {
return Collections.emptyList();
}
}
public String getTemplatePath() {
BrixNode template = getTemplate();
return template != null ? SitePlugin.get().pathForNode(template) : null;
}
public TemplateNode getTemplate() {
if (hasProperty(Properties.TEMPLATE)) {
return (TemplateNode) getProperty(Properties.TEMPLATE).getNode();
} else {
return null;
}
}
public Collection<String> getTileIDs() {
Set<String> keys = new HashSet<String>();
PageMarkupSource source = new PageMarkupSource(this);
Item i = source.nextMarkupItem();
while (i != null) {
if (i instanceof TileTag) {
keys.add(((TileTag) i).getTileName());
}
i = source.nextMarkupItem();
}
keys.addAll(SitePlugin.get().getGlobalTileIDs(getSession()));
return keys;
}
public BrixNode getTileNode(String id) {
BrixNode node = null;
AbstractContainer container = this;
while (node == null && container != null) {
node = container.tiles().getTile(id);
container = container.getTemplate();
}
if (node == null) {
container = SitePlugin.get().getGlobalContainer(getSession());
if (container != null) {
node = container.tiles().getTile(id);
}
}
return node;
}
public String getTitle() {
if (hasProperty(Properties.TITLE)) {
return getProperty(Properties.TITLE).getString();
} else {
return null;
}
}
public String getVariableValue(String key, boolean followTemplate) {
if (hasNode(VARIABLES_NODE_NAME)) {
JcrNode node = getNode(VARIABLES_NODE_NAME);
if (node.hasProperty(key)) {
return node.getProperty(key).getString();
}
}
if (followTemplate) {
TemplateNode template = getTemplate();
if (template != null) {
return template.getVariableValue(key);
} else {
return SitePlugin.get().getGlobalVariableValue(getSession(), key);
}
}
return null;
}
public void setRequiresSSL(Boolean value) {
if (value == null) {
setProperty(Properties.REQUIRES_SSL, (String) null);
} else if (value == false) {
setProperty(Properties.REQUIRES_SSL, false);
} else {
setProperty(Properties.REQUIRES_SSL, true);
}
}
public void setTemplatePath(String path) {
if (path == null) {
setTemplate(null);
} else {
BrixNode node = (BrixNode) SitePlugin.get().nodeForPath(this, path);
if (node == null) {
throw new NodeNotFoundException("No node found on path '" + path + "'.");
}
setTemplate((BrixNode) node);
}
}
public void setTemplate(BrixNode node) {
setProperty(Properties.TEMPLATE, node);
}
public void setTitle(String title) {
setProperty(Properties.TITLE, title);
}
public void setVariableValue(String key, String value) {
final JcrNode node;
if (hasNode(VARIABLES_NODE_NAME)) {
node = getNode(VARIABLES_NODE_NAME);
} else {
node = addNode(VARIABLES_NODE_NAME, "nt:unstructured");
}
node.setProperty(key, value);
}
public TileContainerFacet tiles() {
return tileManager;
}
private static class Properties {
public static final String TITLE = Brix.NS_PREFIX + "title";
public static final String TEMPLATE = Brix.NS_PREFIX + "template";
public static final String REQUIRES_SSL = Brix.NS_PREFIX + "requiresSSL";
}
}