Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,356 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.Syntax; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperator; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.PropertyAccess; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Patterns; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; +import org.apache.sling.scripting.sightly.impl.html.MarkupUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation for the attribute plugin + */ +@Component +@Service +@Properties({ + @Property(name = "service.description", value = "Sightly Resource Block Plugin"), + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "attribute"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 150) +}) +public class AttributePlugin extends PluginComponent { + + private static final Logger log = LoggerFactory.getLogger(AttributePlugin.class); + + @Override + public PluginInvoke invoke(Expression expression, PluginCallInfo callInfo, CompilerContext compilerContext) { + String attributeName = decodeAttributeName(callInfo); + if (attributeName != null && MarkupUtils.isSensitiveAttribute(attributeName)) { + log.warn("Refusing to generate attribute {} for security reasons", attributeName); + return new DefaultPluginInvoke(); //no-op invocation + } + return (attributeName != null) + ? new SingleAttributeInvoke(attributeName, expression, compilerContext) + : new MultiAttributeInvoke(expression.getRoot(), compilerContext); + } + + private String decodeAttributeName(PluginCallInfo info) { + String[] arguments = info.getArguments(); + if (arguments.length == 0) { + return null; + } + return StringUtils.join(arguments, '-'); + } + + private final class SingleAttributeInvoke extends DefaultPluginInvoke { + private final String attributeName; + private final String isTrueValue; + private final String escapedAttrValue; + private final String shouldDisplayAttribute; + + private boolean writeAtEnd = true; + private boolean beforeCall = true; + private final String attrValue; + private final ExpressionNode node; + private final ExpressionNode contentNode; + + private SingleAttributeInvoke(String attributeName, Expression expression, CompilerContext compilerContext) { + this.attributeName = attributeName; + this.attrValue = compilerContext.generateVariable("attrValue_" + attributeName); + this.escapedAttrValue = compilerContext.generateVariable("attrValueEscaped_" + attributeName); + this.isTrueValue = compilerContext.generateVariable("isTrueValue_" + attributeName); + this.shouldDisplayAttribute = compilerContext.generateVariable("shouldDisplayAttr_" + attributeName); + this.node = expression.getRoot(); + if (!expression.containsOption(Syntax.CONTEXT_OPTION)) { + this.contentNode = escapeNodeWithHint(compilerContext, new Identifier(attrValue), MarkupContext.ATTRIBUTE, + new StringConstant(attributeName)); + } else { + this.contentNode = new Identifier(attrValue); + } + } + + @Override + public void beforeAttribute(PushStream stream, String attributeName) { + if (attributeName.equals(this.attributeName)) { + if (beforeCall) { + emitStart(stream); + } + writeAtEnd = false; + } + } + + @Override + public void beforeAttributeValue(PushStream stream, String attributeName, ExpressionNode attributeValue) { + if (attributeName.equals(this.attributeName) && beforeCall) { + emitWrite(stream); + Patterns.beginStreamIgnore(stream); + } + } + + @Override + public void afterAttributeValue(PushStream stream, String attributeName) { + if (attributeName.equals(this.attributeName) && beforeCall) { + Patterns.endStreamIgnore(stream); + } + } + + @Override + public void afterAttribute(PushStream stream, String attributeName) { + if (attributeName.equals(this.attributeName) && beforeCall) { + emitEnd(stream); + } + } + + @Override + public void afterAttributes(PushStream stream) { + if (writeAtEnd) { + emitStart(stream); + stream.emit(new OutText(" " + this.attributeName)); + emitWrite(stream); + emitEnd(stream); + } + } + + @Override + public void onPluginCall(PushStream stream, PluginCallInfo callInfo, Expression expression) { + if ("attribute".equals(callInfo.getName())) { + String attributeName = decodeAttributeName(callInfo); + if (this.attributeName.equals(attributeName)) { + beforeCall = false; + } + } + } + + private void emitStart(PushStream stream) { + stream.emit(new VariableBinding.Start(attrValue, node)); + stream.emit(new VariableBinding.Start(escapedAttrValue, contentNode)); + stream.emit( + new VariableBinding.Start( + shouldDisplayAttribute, + new BinaryOperation( + BinaryOperator.OR, + new Identifier(escapedAttrValue), + new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue)) + ) + ) + ); + stream.emit(new Conditional.Start(shouldDisplayAttribute, true)); + } + + private void emitWrite(PushStream stream) { + stream.emit(new VariableBinding.Start(isTrueValue, + new BinaryOperation(BinaryOperator.EQ, + new Identifier(attrValue), + BooleanConstant.TRUE))); + stream.emit(new Conditional.Start(isTrueValue, false)); + stream.emit(new OutText("=\"")); + stream.emit(new OutVariable(escapedAttrValue)); + stream.emit(new OutText("\"")); + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + } + + private void emitEnd(PushStream stream) { + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + } + } + + private final class MultiAttributeInvoke extends DefaultPluginInvoke { + + private final ExpressionNode attrMap; + private final String attrMapVar; + private final CompilerContext compilerContext; + private boolean beforeCall = true; + private final Set<String> ignored = new HashSet<String>(); + + private MultiAttributeInvoke(ExpressionNode attrMap, CompilerContext context) { + this.attrMap = attrMap; + this.compilerContext = context; + this.attrMapVar = context.generateVariable("attrMap"); + } + + @Override + public void beforeAttributes(PushStream stream) { + stream.emit(new VariableBinding.Start(attrMapVar, attrMap)); + } + + @Override + public void beforeAttribute(PushStream stream, String attributeName) { + ignored.add(attributeName); + if (beforeCall) { + String attrNameVar = compilerContext.generateVariable("attrName_" + attributeName); + String attrValue = compilerContext.generateVariable("mapContains_" + attributeName); + stream.emit(new VariableBinding.Start(attrNameVar, new StringConstant(attributeName))); + stream.emit(new VariableBinding.Start(attrValue, attributeValueNode(new StringConstant(attributeName)))); + writeAttribute(stream, attrNameVar, attrValue); + stream.emit(new Conditional.Start(attrValue, false)); + } + } + + @Override + public void afterAttribute(PushStream stream, String attributeName) { + if (beforeCall) { + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + } + } + + @Override + public void onPluginCall(PushStream stream, PluginCallInfo callInfo, Expression expression) { + if ("attribute".equals(callInfo.getName())) { + String attrName = decodeAttributeName(callInfo); + if (attrName == null) { + beforeCall = false; + } else { + if (!beforeCall) { + ignored.add(attrName); + } + } + } + } + + @Override + public void afterAttributes(PushStream stream) { + HashMap<String, ExpressionNode> ignoredLiteralMap = new HashMap<String, ExpressionNode>(); + for (String attr : ignored) { + ignoredLiteralMap.put(attr, new BooleanConstant(true)); + } + MapLiteral ignoredLiteral = new MapLiteral(ignoredLiteralMap); + String ignoredVar = compilerContext.generateVariable("ignoredAttributes"); + stream.emit(new VariableBinding.Start(ignoredVar, ignoredLiteral)); + String attrNameVar = compilerContext.generateVariable("attrName"); + String attrNameEscaped = compilerContext.generateVariable("attrNameEscaped"); + String attrIndex = compilerContext.generateVariable("attrIndex"); + stream.emit(new Loop.Start(attrMapVar, attrNameVar, attrIndex)); + stream.emit(new VariableBinding.Start(attrNameEscaped, + escapeNode(new Identifier(attrNameVar), MarkupContext.ATTRIBUTE_NAME, null))); + stream.emit(new Conditional.Start(attrNameEscaped, true)); + String isIgnoredAttr = compilerContext.generateVariable("isIgnoredAttr"); + stream.emit( + new VariableBinding.Start(isIgnoredAttr, new PropertyAccess(new Identifier(ignoredVar), new Identifier(attrNameVar)))); + stream.emit(new Conditional.Start(isIgnoredAttr, false)); + String attrContent = compilerContext.generateVariable("attrContent"); + stream.emit(new VariableBinding.Start(attrContent, attributeValueNode(new Identifier(attrNameVar)))); + writeAttribute(stream, attrNameEscaped, attrContent); + stream.emit(VariableBinding.END); //end of attrContent + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + stream.emit(Loop.END); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + } + + private void writeAttribute(PushStream stream, String attrNameVar, String attrContentVar) { + String escapedContent = compilerContext.generateVariable("attrContentEscaped"); + String shouldDisplayAttribute = compilerContext.generateVariable("shouldDisplayAttr"); + stream.emit(new VariableBinding.Start(escapedContent, + escapedExpression(new Identifier(attrContentVar), new Identifier(attrNameVar)))); + stream.emit( + new VariableBinding.Start( + shouldDisplayAttribute, + new BinaryOperation( + BinaryOperator.OR, + new Identifier(escapedContent), + new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrContentVar)) + ) + ) + ); + stream.emit(new Conditional.Start(shouldDisplayAttribute, true)); + stream.emit(new OutText(" ")); //write("attrName"); + writeAttributeName(stream, attrNameVar); + writeAttributeValue(stream, escapedContent, attrContentVar); + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + } + + private void writeAttributeName(PushStream stream, String attrNameVar) { + stream.emit(new OutVariable(attrNameVar)); + } + + private void writeAttributeValue(PushStream stream, String escapedContent, String attrContentVar) { + + String isTrueVar = compilerContext.generateVariable("isTrueAttr"); // holds the comparison (attrValue == true) + stream.emit(new VariableBinding.Start(isTrueVar, //isTrueAttr = (attrContent == true) + new BinaryOperation(BinaryOperator.EQ, new Identifier(attrContentVar), BooleanConstant.TRUE))); + stream.emit(new Conditional.Start(isTrueVar, false)); //if (!isTrueAttr) + stream.emit(new OutText("=\"")); + + stream.emit(new OutVariable(escapedContent)); //write(escapedContent) + + stream.emit(new OutText("\"")); + stream.emit(Conditional.END); //end if isTrueAttr + stream.emit(VariableBinding.END); //end scope for isTrueAttr + } + + private ExpressionNode attributeValueNode(ExpressionNode attributeNameNode) { + return new PropertyAccess(new Identifier(attrMapVar), attributeNameNode); + } + + private ExpressionNode escapedExpression(ExpressionNode original, ExpressionNode hint) { + return escapeNode(original, MarkupContext.ATTRIBUTE, hint); + } + + private ExpressionNode escapeNode(ExpressionNode node, MarkupContext markupContext, ExpressionNode hint) { + return escapeNodeWithHint(compilerContext, node, markupContext, hint); + } + } + + private static ExpressionNode escapeNodeWithHint(CompilerContext compilerContext, ExpressionNode node, MarkupContext markupContext, + ExpressionNode hint) { + if (hint != null) { + //todo: this is not the indicated way to escape via XSS. Correct after modifying the compiler context API + return new RuntimeCall("xss", node, new StringConstant(markupContext.getName()), hint); + } + return compilerContext.adjustToContext(new Expression(node), markupContext).getRoot(); + } +}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/CallPlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/CallPlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/CallPlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/CallPlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,75 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Patterns; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * Implementation for the {@code data-sly-call} plugin. + */ +@Component +@Service(Plugin.class) +@Properties({ + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "call"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 3) +}) +public class CallPlugin extends PluginComponent { + + @Override + public PluginInvoke invoke(final Expression expression, + final PluginCallInfo callInfo, + final CompilerContext compilerContext) { + if (callInfo.getArguments().length > 0) { + throw new PluginException(this, "Call plugin should have no arguments"); + } + return new DefaultPluginInvoke() { + + @Override + public void beforeChildren(PushStream stream) { + String templateVar = compilerContext.generateVariable("templateVar"); + String argsVar = compilerContext.generateVariable("templateOptions"); + MapLiteral args = new MapLiteral(expression.getOptions()); + stream.emit(new VariableBinding.Start(templateVar, expression.getRoot())); + stream.emit(new VariableBinding.Start(argsVar, args)); + stream.emit(new Procedure.Call(templateVar, argsVar)); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + //ignoring everything else + Patterns.beginStreamIgnore(stream); + } + + @Override + public void afterChildren(PushStream stream) { + Patterns.endStreamIgnore(stream); + } + + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/CallPlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,99 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * Implementation for the {@code data-sly-element} plugin. + */ +@Component +@Service +@Properties({ + @Property(name = "service.description", value = "Sightly Resource Block Plugin"), + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "element"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = PluginComponent.DEFAULT_PRIORITY) +}) +public class ElementPlugin extends PluginComponent { + + @Override + public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) { + + return new DefaultPluginInvoke() { + + private final ExpressionNode node = compilerContext.adjustToContext(expression, MarkupContext.ELEMENT_NAME).getRoot(); + private String tagVar = compilerContext.generateVariable("tagVar"); + + @Override + public void beforeElement(PushStream stream, String tagName) { + stream.emit(new VariableBinding.Start(tagVar, node)); + } + + @Override + public void beforeTagOpen(PushStream stream) { + stream.emit(new Conditional.Start(tagVar, true)); + stream.emit(new OutText("<")); + stream.emit(new OutVariable(tagVar)); + stream.emit(Conditional.END); + stream.emit(new Conditional.Start(tagVar, false)); + } + + @Override + public void beforeAttributes(PushStream stream) { + stream.emit(Conditional.END); + } + + @Override + public void beforeTagClose(PushStream stream, boolean isSelfClosing) { + if (!isSelfClosing) { + stream.emit(new Conditional.Start(tagVar, true)); + stream.emit(new OutText("</")); + stream.emit(new OutVariable(tagVar)); + stream.emit(new OutText(">")); + stream.emit(Conditional.END); + } + stream.emit(new Conditional.Start(tagVar, false)); + } + + @Override + public void afterTagClose(PushStream stream, boolean isSelfClosing) { + stream.emit(Conditional.END); + } + + @Override + public void afterElement(PushStream stream) { + stream.emit(VariableBinding.END); + } + }; + + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/IncludePlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/IncludePlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/IncludePlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/IncludePlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,74 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Patterns; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * Implementation for the include plugin + */ +@Component +@Service(Plugin.class) +@Properties({ + @Property(name = "service.description", value = "Sightly Include Block Plugin"), + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "include"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = PluginComponent.DEFAULT_PRIORITY) +}) +public class IncludePlugin extends PluginComponent { + + public static final String FUNCTION = "include"; + + @Override + public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) { + return new DefaultPluginInvoke() { + + @Override + public void beforeChildren(PushStream stream) { + String includedContentVar = compilerContext.generateVariable("includedResult"); + String pathVar = compilerContext.generateVariable("includePath"); + stream.emit(new VariableBinding.Start(pathVar, expression.getRoot())); + stream.emit(new VariableBinding.Start(includedContentVar, + new RuntimeCall(FUNCTION, new Identifier(pathVar), new MapLiteral(expression.getOptions())))); + stream.emit(new OutVariable(includedContentVar)); + stream.emit(VariableBinding.END); //end includedContentVar + stream.emit(VariableBinding.END); //end pathVar + Patterns.beginStreamIgnore(stream); + } + + @Override + public void afterChildren(PushStream stream) { + Patterns.endStreamIgnore(stream); + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/IncludePlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,139 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import java.util.HashMap; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.Syntax; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperator; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.UnaryOperation; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.UnaryOperator; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * Default implementation of the {@code data-sly-list} plugin. + */ +@Component() +@Service(Plugin.class) +@Properties({ + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "list"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 130) +}) +public class ListPlugin extends PluginComponent { + + + private static final String INDEX = "index"; + private static final String COUNT = "count"; + private static final String FIRST = "first"; + private static final String MIDDLE = "middle"; + private static final String LAST = "last"; + private static final String ODD = "odd"; + private static final String EVEN = "even"; + + @Override + public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) { + return new DefaultPluginInvoke() { + + private String listVariable = compilerContext.generateVariable("collectionVar"); + private String collectionSizeVar = compilerContext.generateVariable("size"); + + @Override + public void beforeElement(PushStream stream, String tagName) { + stream.emit(new VariableBinding.Start(listVariable, expression.getRoot())); + stream.emit(new VariableBinding.Start(collectionSizeVar, + new UnaryOperation(UnaryOperator.LENGTH, new Identifier(listVariable)))); + stream.emit(new Conditional.Start(collectionSizeVar, true)); + + } + + @Override + public void beforeChildren(PushStream stream) { + String itemVariable = decodeItemVariable(); + String loopStatusVar = Syntax.itemLoopStatusVariable(itemVariable); + String indexVariable = compilerContext.generateVariable("index"); + stream.emit(new Loop.Start(listVariable, itemVariable, indexVariable)); + stream.emit(new VariableBinding.Start(loopStatusVar, buildStatusObj(indexVariable, collectionSizeVar))); + } + + @Override + public void afterChildren(PushStream stream) { + stream.emit(VariableBinding.END); + stream.emit(Loop.END); + } + + @Override + public void afterElement(PushStream stream) { + stream.emit(Conditional.END); + stream.emit(VariableBinding.END); + stream.emit(VariableBinding.END); + } + + + private String decodeItemVariable() { + String[] args = callInfo.getArguments(); + if (args.length > 0) { + return args[0]; + } + return Syntax.DEFAULT_LIST_ITEM_VAR_NAME; + } + + private MapLiteral buildStatusObj(String indexVar, String sizeVar) { + HashMap<String, ExpressionNode> obj = new HashMap<String, ExpressionNode>(); + Identifier indexId = new Identifier(indexVar); + BinaryOperation firstExpr = new BinaryOperation(BinaryOperator.EQ, indexId, NumericConstant.ZERO); + BinaryOperation lastExpr = new BinaryOperation( + BinaryOperator.EQ, + indexId, + new BinaryOperation(BinaryOperator.SUB, new Identifier(sizeVar), NumericConstant.ONE)); + obj.put(INDEX, indexId); + obj.put(COUNT, new BinaryOperation(BinaryOperator.ADD, indexId, NumericConstant.ONE)); + obj.put(FIRST, firstExpr); + obj.put(MIDDLE, new UnaryOperation( + UnaryOperator.NOT, + new BinaryOperation(BinaryOperator.OR, firstExpr, lastExpr))); + obj.put(LAST, lastExpr); + obj.put(ODD, parityCheck(indexId, NumericConstant.ZERO)); + obj.put(EVEN, parityCheck(indexId, NumericConstant.ONE)); + return new MapLiteral(obj); + } + + private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) { + return new BinaryOperation( + BinaryOperator.EQ, + new BinaryOperation(BinaryOperator.REM, numericExpression, NumericConstant.TWO), + expected); + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/MarkupContext.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/MarkupContext.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/MarkupContext.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/MarkupContext.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,71 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import java.util.HashMap; +import java.util.Map; + +/** + * Indicates what type of content is being rendered + */ +public enum MarkupContext { + + HTML("html"), + TEXT("text"), + ELEMENT_NAME("elementName"), + ATTRIBUTE_NAME("attributeName"), + ATTRIBUTE("attribute"), + URI("uri"), + SCRIPT_TOKEN("scriptToken"), + SCRIPT_STRING("scriptString"), + SCRIPT_COMMENT("scriptComment"), + SCRIPT_REGEXP("scriptRegExp"), + STYLE_TOKEN("styleToken"), + STYLE_STRING("styleString"), + COMMENT("comment"), + NUMBER("number"), + UNSAFE("unsafe"); + + private final String name; + + MarkupContext(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + /** + * Return the render context with the given name + * @param name - the name of the render context + * @return - the rendering context value or null if the name matches no value + */ + public static MarkupContext lookup(String name) { + return reverseMap.get(name); + } + + private static final Map<String, MarkupContext> reverseMap = new HashMap<String, MarkupContext>(); + + static { + for (MarkupContext markupContext : MarkupContext.values()) { + reverseMap.put(markupContext.getName(), markupContext); + } + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/MarkupContext.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/Plugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/Plugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/Plugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/Plugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,55 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; + +/** + * Common interface for plugins + */ +public interface Plugin extends Comparable<Plugin> { + + String SCR_PROP_NAME_BLOCK_NAME = "org.apache.sling.scripting.sightly.impl.plugin.name"; + String SCR_PROP_NAME_PRIORITY = "org.apache.sling.scripting.sightly.impl.plugin.priority"; + + /** + * Given the plugin invocation provide an invoke object which will influence the rendering command + * stream + * @param expression the expression used at plugin invocation + * @param callInfo the parameters given to the plugin + * @param compilerContext a compiler context providing utility methods to plugins + * @return an invocation + * @see PluginInvoke + */ + PluginInvoke invoke(Expression expression, PluginCallInfo callInfo, CompilerContext compilerContext); + + /** + * The priority of the plugin + * @return a numeric value which controls when, relative to other plugins, should + * this plugin be applied + */ + int priority(); + + /** + * The name of the plugin + * @return the plugin name + */ + String name(); +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/Plugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginCallInfo.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginCallInfo.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginCallInfo.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginCallInfo.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,49 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +/** + * Data related to a plugin call + */ +public class PluginCallInfo { + + private final String name; + private final String[] arguments; + + public PluginCallInfo(String name, String[] arguments) { + this.name = name; + this.arguments = arguments; + } + + /** + * Get the name of the called plugin + * @return a string with the name of the called plugin + */ + public String getName() { + return name; + } + + /** + * Get the plugin arguments + * @return a possibly empty array of args + */ + public String[] getArguments() { + return arguments; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginCallInfo.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginComponent.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginComponent.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginComponent.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginComponent.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,61 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import java.util.Dictionary; + +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.ComponentException; + +/** + * Component plugin implementation + */ +public abstract class PluginComponent implements Plugin { + + public static final int DEFAULT_PRIORITY = 100; + + private int priority; + private String name; + + @Override + public int priority() { + return priority; + } + + @Override + public String name() { + return name; + } + + @Override + public int compareTo(Plugin o) { + return this.priority() - o.priority(); + } + + @SuppressWarnings("UnusedDeclaration") + protected void activate(ComponentContext componentContext) { + Dictionary properties = componentContext.getProperties(); + priority = PropertiesUtil.toInteger(properties.get(SCR_PROP_NAME_PRIORITY), DEFAULT_PRIORITY); + name = PropertiesUtil.toString(properties.get(SCR_PROP_NAME_BLOCK_NAME), null); + if (name == null) { + throw new ComponentException("The plugin hasn't a valid name specified"); + } + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginComponent.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginException.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginException.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginException.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginException.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,36 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +/** + * Plugin runtime exception caused by a plugin + */ +public class PluginException extends RuntimeException { + + private Plugin plugin; + + public PluginException(Plugin plugin, String message) { + super(message); + this.plugin = plugin; + } + + public Plugin getPlugin() { + return plugin; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginInvoke.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginInvoke.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginInvoke.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginInvoke.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,60 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * General interface for plugins + */ +public interface PluginInvoke { + + void beforeElement(PushStream stream, String tagName); + + void beforeTagOpen(PushStream stream); + + void beforeAttributes(PushStream stream); + + void beforeAttribute(PushStream stream, String attributeName); + + void beforeAttributeValue(PushStream stream, String attributeName, ExpressionNode attributeValue); + + void afterAttributeValue(PushStream stream, String attributeName); + + void afterAttribute(PushStream stream, String attributeName); + + void onPluginCall(PushStream stream, PluginCallInfo callInfo, Expression expression); + + void afterAttributes(PushStream stream); + + void afterTagOpen(PushStream stream); + + void beforeChildren(PushStream stream); + + void afterChildren(PushStream stream); + + void beforeTagClose(PushStream stream, boolean isSelfClosing); + + void afterTagClose(PushStream stream, boolean isSelfClosing); + + void afterElement(PushStream stream); + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/PluginInvoke.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ResourcePlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ResourcePlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ResourcePlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ResourcePlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,78 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Patterns; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * The resource plugin + */ +@Component +@Service(Plugin.class) +@Properties({ + @Property(name = "service.description", value = "Sightly Resource Block Plugin"), + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "resource"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = PluginComponent.DEFAULT_PRIORITY) +}) +public class ResourcePlugin extends PluginComponent { + + public static final String FUNCTION = "includeResource"; + + @Override + public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) { + + return new DefaultPluginInvoke() { + + private Map<String, ExpressionNode> expressionOptions = new HashMap<String, ExpressionNode>(expression.getOptions()); + + @Override + public void beforeChildren(PushStream stream) { + String resourceVar = compilerContext.generateVariable("resourceContent"); + stream.emit(new VariableBinding.Start(resourceVar, + new RuntimeCall(FUNCTION, + expression.getRoot(), new MapLiteral(expressionOptions)))); + stream.emit(new OutVariable(resourceVar)); + stream.emit(VariableBinding.END); + Patterns.beginStreamIgnore(stream); + } + + @Override + public void afterChildren(PushStream stream) { + Patterns.endStreamIgnore(stream); + } + + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ResourcePlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TemplatePlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TemplatePlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TemplatePlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TemplatePlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,98 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import java.util.Map; +import java.util.Set; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Patterns; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * The template plugin + */ +@Component +@Service +@Properties({ + @Property(name = "service.description", value = "Sightly Template Block Plugin"), + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "template"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = Integer.MIN_VALUE) +}) +public class TemplatePlugin extends PluginComponent { + @Override + public PluginInvoke invoke(final Expression expressionNode, final PluginCallInfo callInfo, CompilerContext compilerContext) { + return new DefaultPluginInvoke() { + + @Override + public void beforeTagOpen(PushStream stream) { + //ignoring template tags + Patterns.beginStreamIgnore(stream); + } + + @Override + public void beforeElement(PushStream stream, String tagName) { + String name = decodeName(); + Set<String> parameters = extractParameters(); + stream.emit(new Procedure.Start(name, parameters)); + } + + @Override + public void afterElement(PushStream stream) { + stream.emit(Procedure.END); + } + + @Override + public void afterTagOpen(PushStream stream) { + Patterns.endStreamIgnore(stream); //resuming normal operation + } + + @Override + public void beforeTagClose(PushStream stream, boolean isSelfClosing) { + Patterns.beginStreamIgnore(stream); //ignoring closing tags + } + + @Override + public void afterTagClose(PushStream stream, boolean isSelfClosing) { + Patterns.endStreamIgnore(stream); + } + + private Set<String> extractParameters() { + Map<String, ExpressionNode> options = expressionNode.getOptions(); + return options.keySet(); + } + + private String decodeName() { + String[] arguments = callInfo.getArguments(); + if (arguments.length == 0) { + throw new PluginException(TemplatePlugin.this, "template name was not provided"); + } + return arguments[0]; + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TemplatePlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,86 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * Implementation for the test plugin + */ +@Component +@Service(Plugin.class) +@Properties({ + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "test"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 1) +}) +public class TestPlugin extends PluginComponent { + + + @Override + public PluginInvoke invoke(final Expression expressionNode, final PluginCallInfo callInfo, final CompilerContext compilerContext) { + + return new DefaultPluginInvoke() { + + private boolean globalBinding; + + @Override + public void beforeElement(PushStream stream, String tagName) { + String variableName = decodeVariableName(); + globalBinding = variableName != null; + if (variableName == null) { + variableName = compilerContext.generateVariable("testVariable"); + } + if (globalBinding) { + stream.emit(new VariableBinding.Global(variableName, expressionNode.getRoot())); + } else { + stream.emit(new VariableBinding.Start(variableName, expressionNode.getRoot())); + } + stream.emit(new Conditional.Start(variableName, true)); + } + + @Override + public void afterElement(PushStream stream) { + stream.emit(Conditional.END); + if (!globalBinding) { + stream.emit(VariableBinding.END); + } + } + + private String decodeVariableName() { + String[] args = callInfo.getArguments(); + if (args.length > 0) { + return args[0]; + } + return null; + } + + }; + } + + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TextPlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TextPlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TextPlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TextPlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,64 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Patterns; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * The {@code data-sly-text} plugin. + */ +@Component +@Service(Plugin.class) +@Properties({ + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "text"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 9) +}) +public class TextPlugin extends PluginComponent { + + @Override + public PluginInvoke invoke(final Expression expression, PluginCallInfo callInfo, final CompilerContext compilerContext) { + return new DefaultPluginInvoke() { + + @Override + public void beforeChildren(PushStream stream) { + String variable = compilerContext.generateVariable("textContent"); + stream.emit(new VariableBinding.Start(variable, + compilerContext.adjustToContext(expression, MarkupContext.TEXT).getRoot())); + stream.emit(new OutVariable(variable)); + stream.emit(VariableBinding.END); + Patterns.beginStreamIgnore(stream); + } + + @Override + public void afterChildren(PushStream stream) { + Patterns.endStreamIgnore(stream); + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TextPlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,93 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant; +import org.apache.sling.scripting.sightly.impl.compiler.ris.Command; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +/** + * The unwrapped plugin + */ +@Component +@Service(Plugin.class) +@Properties({ + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "unwrap"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 125) +}) +public class UnwrapPlugin extends PluginComponent { + + @Override + public PluginInvoke invoke(final Expression expression, PluginCallInfo callInfo, final CompilerContext compilerContext) { + return new DefaultPluginInvoke() { + + private final String variable = compilerContext.generateVariable("unwrapCondition"); + private final Command unwrapTest = new Conditional.Start(variable, false); + + @Override + public void beforeElement(PushStream stream, String tagName) { + stream.emit(new VariableBinding.Start(variable, testNode())); + } + + @Override + public void beforeTagOpen(PushStream stream) { + stream.emit(unwrapTest); + } + + @Override + public void afterTagOpen(PushStream stream) { + stream.emit(Conditional.END); + } + + @Override + public void beforeTagClose(PushStream stream, boolean isSelfClosing) { + stream.emit(unwrapTest); + } + + @Override + public void afterTagClose(PushStream stream, boolean isSelfClosing) { + stream.emit(Conditional.END); + } + + @Override + public void afterElement(PushStream stream) { + stream.emit(VariableBinding.END); + } + + private ExpressionNode testNode() { + return (isEmptyExpression(expression.getRoot())) ? BooleanConstant.TRUE : expression.getRoot(); + } + + private boolean isEmptyExpression(ExpressionNode node) { + return node instanceof StringConstant && ((StringConstant) node).getText().isEmpty(); + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UsePlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UsePlugin.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UsePlugin.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UsePlugin.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,68 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.scripting.sightly.impl.plugin; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall; +import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding; +import org.apache.sling.scripting.sightly.impl.compiler.common.DefaultPluginInvoke; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream; + +@Component +@Service +@Properties({ + @Property(name = "service.description", value = "Sightly Use Block Plugin"), + @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "use"), + @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 1) +}) +public class UsePlugin extends PluginComponent { + + public static final String FUNCTION_NAME = "use"; + + private static final String DEFAULT_VARIABLE_NAME = "useBean"; + + @Override + public PluginInvoke invoke(final Expression expression, + final PluginCallInfo callInfo, + final CompilerContext compilerContext) { + return new DefaultPluginInvoke() { + + @Override + public void beforeElement(PushStream stream, String tagName) { + String variableName = decodeVariableName(); + stream.emit(new VariableBinding.Global(variableName, + new RuntimeCall(FUNCTION_NAME, expression.getRoot(), new MapLiteral(expression.getOptions())))); + } + + private String decodeVariableName() { + String[] arguments = callInfo.getArguments(); + if (arguments.length > 0) { + return arguments[0]; + } + return DEFAULT_VARIABLE_NAME; + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UsePlugin.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/package-info.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/package-info.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/package-info.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,22 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + ******************************************************************************/ +@Version("1.0.0") +package org.apache.sling.scripting.sightly; + +import aQute.bnd.annotation.Version; Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain