You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2014/11/14 15:05:03 UTC
svn commit: r1639641 [11/15] - in /sling/trunk/contrib/scripting/sightly: ./
engine/ engine/src/ engine/src/main/ engine/src/main/antlr4/
engine/src/main/antlr4/org/ engine/src/main/antlr4/org/apache/
engine/src/main/antlr4/org/apache/sling/ engine/src...
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateAttribute.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateAttribute.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateAttribute.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateAttribute.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.html.dom.template;
+
+public class TemplateAttribute {
+
+ private final String name;
+
+ private final String value;
+
+ public TemplateAttribute(final String name, final String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public boolean hasValue() {
+ return value != null;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateCommentNode.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateCommentNode.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateCommentNode.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateCommentNode.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.html.dom.template;
+
+public class TemplateCommentNode extends TemplateNode {
+
+ private final String text;
+
+ public TemplateCommentNode(final String t) {
+ this.text = t;
+ }
+
+ public String getText() {
+ return this.text;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateElementNode.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateElementNode.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateElementNode.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateElementNode.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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.html.dom.template;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TemplateElementNode extends TemplateNode {
+
+ private final String name;
+
+ private final boolean hasEndSlash;
+
+ private boolean hasEndElement = false;
+
+ private boolean hasStartElement = false;
+
+ private final List<TemplateAttribute> attributes;
+
+ private final List<TemplateNode> children = new ArrayList<TemplateNode>();
+
+ public TemplateElementNode(final String name,
+ final boolean hasEndSlash,
+ final List<TemplateAttribute> attributes) {
+ this.name = name;
+ this.hasEndSlash = hasEndSlash;
+ this.attributes = attributes;
+ }
+
+ public void setHasStartElement() {
+ this.hasStartElement = true;
+ }
+
+ public void setHasEndElement() {
+ this.hasEndElement = true;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isHasEndSlash() {
+ return hasEndSlash;
+ }
+
+ public boolean isHasStartElement() {
+ return hasStartElement;
+ }
+
+ public boolean isHasEndElement() {
+ return hasEndElement;
+ }
+
+ public List<TemplateAttribute> getAttributes() {
+ return attributes;
+ }
+
+ public void addChild(final TemplateNode node) {
+ this.children.add(node);
+ }
+
+ public List<TemplateNode> getChildren() {
+ return this.children;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateNode.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateNode.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateNode.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateNode.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.html.dom.template;
+
+public abstract class TemplateNode {
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateParser.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateParser.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateParser.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateParser.java Fri Nov 14 14:04:56 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.html.dom.template;
+
+import org.apache.sling.scripting.sightly.html.dom.AttributeList;
+import org.apache.sling.scripting.sightly.html.dom.DocumentHandler;
+import org.apache.sling.scripting.sightly.html.dom.HtmlParser;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Deque;
+import java.util.ArrayDeque;
+
+/**
+ * The template parser parses an HTML document and returns a reusable tree
+ * representation.
+ */
+public class TemplateParser {
+
+ /**
+ * Parse an html document
+ * @param reader to be parsed
+ * @throws IOException in case of any parsing error
+ *
+ * @return a Template
+ */
+ public Template parse(final Reader reader) throws IOException {
+ final TemplateParserContext context = new TemplateParserContext();
+
+ HtmlParser.parse(reader, context);
+
+ return context.getTemplate();
+ }
+
+ public static final class TemplateParserContext implements DocumentHandler {
+
+ /** Used for text/character events */
+ private StringBuilder textBuilder = new StringBuilder();
+
+ /** Element stack - root is the Template */
+ private final Deque<TemplateElementNode> elementStack = new ArrayDeque<TemplateElementNode>();
+
+ /** The template. */
+ private Template template;
+
+ public Template getTemplate() {
+ return this.template;
+ }
+
+ public void onStart() throws IOException {
+ this.template = new Template();
+ this.elementStack.push(this.template);
+ }
+
+ public void onEnd() throws IOException {
+ this.checkText();
+ this.elementStack.clear();
+ }
+
+ private void checkText() {
+ if (textBuilder.length() > 0) {
+ elementStack.peek().addChild(new TemplateTextNode(textBuilder.toString()));
+ this.textBuilder = new StringBuilder();
+ }
+ }
+
+ public void onStartElement(String name, AttributeList attList, boolean endSlash) {
+ this.checkText();
+ final List<TemplateAttribute> attrs = new ArrayList<TemplateAttribute>();
+ final Iterator<String> iter = attList.attributeNames();
+ while ( iter.hasNext() ) {
+ final String aName = iter.next();
+ final TemplateAttribute attr = new TemplateAttribute(aName, attList.getValue(aName));
+ attrs.add(attr);
+ }
+ final TemplateElementNode element = new TemplateElementNode(name, endSlash, attrs);
+ element.setHasStartElement();
+ elementStack.peek().addChild(element);
+ if ( !endSlash ) {
+ elementStack.push(element);
+ }
+ }
+
+ public void onEndElement(String name) {
+ this.checkText();
+ if (contains(name)) {
+ TemplateElementNode element = this.elementStack.pop();
+ while ( !name.equals(element.getName()) ) {
+ element = this.elementStack.pop();
+ }
+ element.setHasEndElement();
+ } else {
+ final TemplateElementNode element
+ = new TemplateElementNode(name, false, new ArrayList<TemplateAttribute>());
+ elementStack.peek().addChild(element);
+ element.setHasEndElement();
+ }
+ }
+
+ public void onCharacters(final char[] ch, final int off, final int len) {
+ textBuilder.append(ch, off, len);
+ }
+
+ public void onComment(final String text) throws IOException {
+ this.checkText();
+ elementStack.peek().addChild(new TemplateCommentNode(text));
+ }
+
+ private boolean contains(String name) {
+ Iterator it = this.elementStack.iterator(); // ascending iterator
+ while (it.hasNext()) {
+ TemplateElementNode elem = (TemplateElementNode) it.next();
+ if (name.equals(elem.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateTextNode.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateTextNode.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateTextNode.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/html/dom/template/TemplateTextNode.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.html.dom.template;
+
+public class TemplateTextNode extends TemplateNode {
+
+ private final String text;
+
+ public TemplateTextNode(final String t) {
+ this.text = t;
+ }
+
+ public String getText() {
+ return this.text;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/AttributePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/AttributePlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/AttributePlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/AttributePlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,360 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.sling.scripting.sightly.compiler.Syntax;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperator;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.MarkupContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Loop;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutText;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.html.MarkupUtils;
+
+/**
+ * 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();
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/CallPlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/CallPlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/CallPlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/CallPlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginException;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.*;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.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);
+ }
+
+ };
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ElementPlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ElementPlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ElementPlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ElementPlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.MarkupContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutText;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.MarkupContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutText;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.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);
+ }
+ };
+
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/IncludePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/IncludePlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/IncludePlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/IncludePlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.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);
+ }
+ };
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ListPlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ListPlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ListPlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ListPlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * 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.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.compiler.Syntax;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperator;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.UnaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.UnaryOperator;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Loop;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.Syntax;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.*;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Loop;
+import org.apache.sling.scripting.sightly.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);
+ }
+ };
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/PluginComponent.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/PluginComponent.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/PluginComponent.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/PluginComponent.java Fri Nov 14 14:04:56 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.plugin;
+
+import java.util.Dictionary;
+
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentException;
+
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+
+/**
+ * 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");
+ }
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ResourcePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ResourcePlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ResourcePlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/ResourcePlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.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);
+ }
+
+ };
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TemplatePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TemplatePlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TemplatePlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TemplatePlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginException;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.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];
+ }
+ };
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TestPlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TestPlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TestPlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TestPlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.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;
+ }
+
+ };
+ }
+
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TextPlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TextPlugin.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TextPlugin.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/plugin/TextPlugin.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.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.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.CompilerContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.MarkupContext;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.Plugin;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.common.DefaultPluginInvoke;
+import org.apache.sling.scripting.sightly.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.compiler.api.expression.Expression;
+import org.apache.sling.scripting.sightly.compiler.api.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Patterns;
+
+/**
+ * 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);
+ }
+ };
+ }
+}