You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2014/11/28 11:18:09 UTC

svn commit: r1642281 [12/14] - in /sling/trunk/contrib/scripting/sightly: ./ engine/ engine/src/main/antlr4/org/apache/sling/parser/expr/generated/ engine/src/main/antlr4/org/apache/sling/scripting/ engine/src/main/antlr4/org/apache/sling/scripting/sig...

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