Modified: sling/trunk/contrib/scripting/sightly/engine/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/pom.xml?rev=1642281&r1=1642280&r2=1642281&view=diff ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/pom.xml (original) +++ sling/trunk/contrib/scripting/sightly/engine/pom.xml Fri Nov 28 10:18:01 2014 @@ -78,9 +78,6 @@ <configuration> <instructions> <Embed-Dependency>antlr4-runtime,org.abego.treelayout.core</Embed-Dependency> - <Export-Package> - org.apache.sling.scripting.sightly.api - </Export-Package> <ScriptEngine-Name>${project.name}</ScriptEngine-Name> <ScriptEngine-Version>${project.version}</ScriptEngine-Version> </instructions>
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4 URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4 (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4 Fri Nov 28 10:18:01 2014 @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +lexer grammar SightlyLexer; + +ESC_EXPR: '\${'.*? '}'; + +EXPR_START: '${' -> pushMode(ExpressionMode); + +TEXT_PART: .; //$hello ${expr} + + +mode ExpressionMode; + +EXPR_END: '}' -> popMode; + + +BOOL_CONSTANT: 'true' | 'false'; + +DOT: '.'; + +LBRACKET: '('; + +RBRACKET: ')'; + +AND_OP: '&&'; + +OR_OP: '||'; + +NOT_OP: '!'; + +COMMA: ','; + +ARRAY_START: '['; + +ARRAY_END: ']'; + +ASSIGN: '='; + +OPTION_SEP: '@'; + +TERNARY_Q_OP: '?'; + +TERNARY_BRANCHES_OP: ':'; + +LT: '<'; + +LEQ: '<='; + +GEQ: '>='; + +GT: '>'; + +EQ: '=='; + +NEQ: '!='; + +// tokens + +ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|':')* + ; + +INT : '0'..'9'+ + ; + +FLOAT + : ('0'..'9')+ '.' ('0'..'9')+ EXPONENT? +// | '.' ('0'..'9')+ EXPONENT? --> conflicts with a.2 notation + | ('0'..'9')+ EXPONENT + ; + +COMMENT: '<!--/*' .*? '*/-->' -> skip; + +WS : ( ' ' + | '\t' + | '\r' + | '\n' + ) -> skip + ; + + +STRING + : '"' ( ESC_SEQ | ~('\\'|'"') )* '"' + | '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\'' + ; + +//CHAR: '\'' ( ESC_SEQ | ~('\''|'\\') ) '\'' +// ; + +fragment +EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; + +fragment +HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; + +fragment +ESC_SEQ + : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') + | UNICODE_ESC + ; + +fragment +UNICODE_ESC + : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT + ; Added: sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4 URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4 (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4 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. + ******************************************************************************/ +parser grammar SightlyParser; + +options { + language = Java; + tokenVocab = SightlyLexer; +} + +@header { +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.*; +import org.apache.sling.scripting.sightly.impl.compiler.expression.*; +import org.apache.sling.scripting.sightly.impl.compiler.frontend.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +} + + +interpolation returns [Interpolation interp] +@init { $interp = new Interpolation(); } + : ( + textFrag { $interp.addText($textFrag.str); } + | expression { $interp.addExpression($expression.expr); } + )* //perhaphs too restrictive + ; + +textFrag returns [String str] +@init { StringBuilder sb = new StringBuilder(); } + : (TEXT_PART { sb.append($TEXT_PART.text); })+ + { $str = sb.toString(); } + | (ESC_EXPR { sb.append($ESC_EXPR.text); })+ + { $str = sb.toString().substring(1); } + ; + +expression returns [Expression expr] +@init { ExpressionNode exNode = NullLiteral.INSTANCE; Map<String, ExpressionNode> opts = Collections.emptyMap(); } + : EXPR_START (exprNode {exNode = $exprNode.node;})? + (OPTION_SEP optionList {opts = $optionList.options;})? + EXPR_END + { $expr = new Expression(exNode, opts); } + ; + + +optionList returns [Map<String, ExpressionNode> options] +@init { $options = new HashMap<String, ExpressionNode>(); } + : f=option { $options.put($f.name, ($f.value != null) ? $f.value : NullLiteral.INSTANCE); } + (COMMA r=option { $options.put($r.name, $r.value); })* + ; + +option returns [String name, ExpressionNode value] + : ID { $name = $ID.text; } (ASSIGN exprNode { $value = $exprNode.node; } )? + ; + + +exprNode returns [ExpressionNode node] + : condition=binaryOp TERNARY_Q_OP thenBranch=binaryOp TERNARY_BRANCHES_OP elseBranch=binaryOp + {$node = new TernaryOperator($condition.node, $thenBranch.node, $elseBranch.node);} + | binaryOp {$node = $binaryOp.node;} + ; + +binaryOp returns [ExpressionNode node] //is there any priority precedence between AND & OR ? + : left=comparisonTerm { $node = $left.node; } + (operator right=comparisonTerm { $node = new BinaryOperation($operator.op, $node, $right.node); })* + ; + +operator returns [BinaryOperator op] + : AND_OP { $op = BinaryOperator.AND; } | OR_OP { $op = BinaryOperator.OR; } + ; + +comparisonTerm returns [ExpressionNode node] + : factor { $node = $factor.node; } + | left=factor comparisonOp right=factor { $node = new BinaryOperation($comparisonOp.op, $left.node, $right.node); } + ; + +comparisonOp returns [BinaryOperator op] + : GT { $op = BinaryOperator.GT; } + | LT { $op = BinaryOperator.LT; } + | LEQ { $op = BinaryOperator.LEQ; } + | GEQ { $op = BinaryOperator.GEQ; } + | EQ { $op = BinaryOperator.STRICT_EQ; } + | NEQ { $op = BinaryOperator.STRICT_NEQ; } + ; + +factor returns [ExpressionNode node] + : (pa=term { $node = $pa.node; }) + | (NOT_OP notTerm=term { $node = new UnaryOperation(UnaryOperator.NOT, $notTerm.node); }) + ; + +term returns [ExpressionNode node] + : simple { $node = $simple.node; } + ( ARRAY_START exprNode ARRAY_END { $node = new PropertyAccess($node, $exprNode.node); } + | DOT field { $node = new PropertyAccess($node, $field.node); })* + ; + +field returns [ExpressionNode node] + : ID { $node = new StringConstant($ID.getText()); } + ; + +simple returns [ExpressionNode node] + : atom { $node = $atom.node; } + | LBRACKET exprNode RBRACKET { $node = $exprNode.node; } + | ARRAY_START valueList ARRAY_END { $node = new ArrayLiteral($valueList.values); } + | ARRAY_START ARRAY_END { $node = new ArrayLiteral(Collections.<ExpressionNode>emptyList()); } + ; + +valueList returns [List<ExpressionNode> values] +@init { $values = new ArrayList<ExpressionNode>(); } + : (f=exprNode { $values.add($f.node); }) (COMMA p=exprNode { $values.add($p.node); })* + ; + +atom returns [Atom node] + : stringConst { $node = $stringConst.node; } + | ID { $node = new Identifier($ID.text); } + | numText=(FLOAT | INT) { $node = new NumericConstant($numText.text); } + | boolText=BOOL_CONSTANT { $node = new BooleanConstant($boolText.text); } + ; + +stringConst returns [StringConstant node] + : STRING { $node = ParserHelper.createStringConstant($STRING.text); } + ; Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/Record.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/Record.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/Record.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/Record.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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; + +import java.util.Set; + +import aQute.bnd.annotation.ProviderType; + +/** + * A key-value immutable object understood by the Sightly runtime + * @param <T> the type of values for this record + */ +@ProviderType +public interface Record<T> { + + /** + * Get the value of the specified property + * @param name the name of the property + * @return the value of the property or null if this record does not + * have the specified property + */ + T get(String name); + + /** + * Get the set of properties for this record + * @return this record's properties + */ + Set<String> properties(); + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/Record.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/ResourceResolution.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/ResourceResolution.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/ResourceResolution.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/ResourceResolution.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,176 @@ +/******************************************************************************* + * 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; + +import org.apache.commons.lang.StringUtils; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceUtil; + +/** + * Utility class which used by the Sightly engine & extensions + * to resolve resources + */ +public final class ResourceResolution { + + /** + * Maximum number of iterations that can be performed when searching for a resource in + * the resource superType chain + */ + private static final int RECURSION_LIMIT = 100; + + /** + * Resolve the resource with the given path relative to the base resource, using the + * resource super type logic + * @param resourceResolver The resource resolver to be used + * @param base the base resource. It can be null if path is absolute + * @param path the path to the resource + * @return the retrieved resource or null if no resource was found + * @throws java.lang.UnsupportedOperationException if the resource is not in the resource resolver's search path + * @throws java.lang.IllegalStateException if the number of steps necessary to search for the resource on the resource + * superType chain has reached the maximum limit + * @throws java.lang.IllegalArgumentException if a null componentResource is provided but the path is not absolute + */ + public static Resource resolveComponentRelative(ResourceResolver resourceResolver, Resource base, String path) { + Resource componentResource = null; + if (base != null) { + if ("nt:file".equals(base.getResourceType())) { + componentResource = retrieveParent(resourceResolver, base); + } else { + componentResource = base; + } + } + return resolveComponent(resourceResolver, componentResource, path); + } + + public static Resource resolveComponentForRequest(ResourceResolver resolver, SlingHttpServletRequest request) { + String resourceType = request.getResource().getResourceType(); + if (StringUtils.isNotEmpty(resourceType)) { + if (resourceType.startsWith("/")) { + return resolver.getResource(resourceType); + } + for (String searchPath : resolver.getSearchPath()) { + String componentPath = ResourceUtil.normalize(searchPath + "/" + resourceType); + Resource componentResource = resolver.getResource(componentPath); + if (componentResource != null) { + return componentResource; + } + } + } + return null; + } + + /** + * Resolve the resource in the specified component + * @param resourceResolver The resource resolver to be used + * @param componentResource The resource for the component. It can be null if path is absolute + * @param path the path to the resource + * @return the retrieved resource or null if no resource was found + * @throws java.lang.UnsupportedOperationException if the resource is not in the resource resolver's search path + * @throws java.lang.IllegalStateException if more than {@link ResourceResolution#RECURSION_LIMIT} steps were + * necessary to search for the resource on the resource superType chain + * @throws java.lang.IllegalArgumentException if a null componentResource is provided but the path is not absolute + */ + private static Resource resolveComponent(ResourceResolver resourceResolver, Resource componentResource, String path) { + if (resourceResolver == null || path == null) { + throw new NullPointerException("Arguments cannot be null"); + } + Resource resource = null; + if (isAbsolutePath(path)) { + resource = resourceResolver.getResource(path); + } + if (resource == null) { + if (componentResource == null) { + throw new IllegalArgumentException("Argument cannot be null if path is not absolute: " + path); + } + resource = recursiveResolution(resourceResolver, componentResource, path); + } + if (resource == null) { + resource = locateInSearchPath(resourceResolver, path); + } + return resource != null ? searchPathChecked(resourceResolver, resource) : null; + } + + private static Resource recursiveResolution(ResourceResolver resourceResolver, Resource componentResource, String path) { + for (int iteration = 0; iteration < RECURSION_LIMIT; iteration++) { + Resource resource = resourceResolver.getResource(componentResource, path); + if (resource != null) { + return resource; + } + componentResource = findSuperComponent(resourceResolver, componentResource); + if (componentResource == null) { + return null; + } + } + //at this point we have reached recursion limit + throw new IllegalStateException("Searching for resource in component chain took more than " + + RECURSION_LIMIT + " steps"); + } + + private static Resource locateInSearchPath(ResourceResolver resourceResolver, String path) { + for (String searchPath : resourceResolver.getSearchPath()) { + String fullPath = searchPath + path; + Resource resource = resourceResolver.getResource(fullPath); + if (resource != null && resource.getPath().startsWith(searchPath)) { //prevent path traversal attack + return resource; + } + } + return null; + } + + private static boolean isInSearchPath(ResourceResolver resourceResolver, Resource resource) { + String resourcePath = resource.getPath(); + for (String path : resourceResolver.getSearchPath()) { + if (resourcePath.startsWith(path)) { + return true; + } + } + return false; + } + + private static Resource findSuperComponent(ResourceResolver resourceResolver, Resource base) { + String superType = resourceResolver.getParentResourceType(base); + if (superType == null) { + return null; + } + return resourceResolver.getResource(superType); + } + + private static Resource searchPathChecked(ResourceResolver resourceResolver, Resource resource) { + if (!isInSearchPath(resourceResolver, resource)) { + throw new UnsupportedOperationException("Access to resource " + resource.getPath() + " is denied, since the resource does not reside on the search path"); + } + return resource; + } + + private static Resource retrieveParent(ResourceResolver resourceResolver, Resource resource) { + String parentPath = ResourceUtil.getParent(resource.getPath()); + if (parentPath == null) { + return null; + } + return resourceResolver.getResource(parentPath); + } + + private static boolean isAbsolutePath(String path) { + return path.startsWith("/"); + } + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/ResourceResolution.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/SightlyException.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/SightlyException.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/SightlyException.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/SightlyException.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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; + +import org.apache.sling.api.SlingException; + +/** + * Exceptions caused by the Sightly engine + */ +public class SightlyException extends SlingException { + + public SightlyException() { + } + + public SightlyException(String message) { + super(message); + } + + public SightlyException(String message, Throwable cause) { + super(message, cause); + } + + public SightlyException(Throwable cause) { + super(cause); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/SightlyException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/ExtensionInstance.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/ExtensionInstance.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/ExtensionInstance.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/ExtensionInstance.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.extension; + +import aQute.bnd.annotation.ConsumerType; + +/** + * An instance of an {@link RuntimeExtension} + */ +@ConsumerType +public interface ExtensionInstance { + + /** + * Call this specific extension + * @param arguments - the arguments for the call + * @return - the result from the call + */ + Object call(Object ... arguments); + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/ExtensionInstance.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtension.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtension.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtension.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtension.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.extension; + +import org.apache.sling.scripting.sightly.render.RenderContext; + +import aQute.bnd.annotation.ConsumerType; + +/** + * Extensions provided to the Sightly runtime + */ +@ConsumerType +public interface RuntimeExtension { + + String SCR_PROP_NAME = "org.apache.sling.scripting.sightly.extension.name"; + + /** + * Provide an instance of this extension + * @param renderContext - the runtime context + * @return an extension instance + */ + ExtensionInstance provide(RenderContext renderContext); +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtension.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtensionException.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtensionException.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtensionException.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtensionException.java Fri Nov 28 10:18:01 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.extension; + +import org.apache.sling.scripting.sightly.SightlyException; + +/** + * Exception thrown by runtime extensions + * @see RuntimeExtension + */ +public class RuntimeExtensionException extends SightlyException { + + public RuntimeExtensionException() { + } + + public RuntimeExtensionException(String message) { + super(message); + } + + public RuntimeExtensionException(String message, Throwable cause) { + super(message, cause); + } + + public RuntimeExtensionException(Throwable cause) { + super(cause); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/RuntimeExtensionException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/package-info.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/package-info.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/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.extension; + +import aQute.bnd.annotation.Version; Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/extension/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/CompilationOutput.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/CompilationOutput.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/CompilationOutput.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/CompilationOutput.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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.compiled; + +import java.util.Map; + +/** + * Result from compilation + */ +public class CompilationOutput { + + private final String mainBody; + private final Map<String, CompilationOutput> subTemplates; + + public CompilationOutput(String mainBody, Map<String, CompilationOutput> subTemplates) { + this.mainBody = mainBody; + this.subTemplates = subTemplates; + } + + public String getMainBody() { + return mainBody; + } + + public Map<String, CompilationOutput> getSubTemplates() { + return subTemplates; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/CompilationOutput.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/ExpressionTranslator.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/ExpressionTranslator.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/ExpressionTranslator.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/ExpressionTranslator.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,185 @@ +/******************************************************************************* + * 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.compiled; + +import java.util.Map; + +import org.apache.sling.scripting.sightly.impl.compiled.operator.BinaryOpGen; +import org.apache.sling.scripting.sightly.impl.compiled.operator.Operators; +import org.apache.sling.scripting.sightly.impl.compiled.operator.UnaryOpGen; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.ArrayLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation; +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.NullLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant; +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.expression.node.TernaryOperator; +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.util.expression.SideEffectVisitor; +import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl; + +/** + * Builds expressions within a sling source file. + */ +public final class ExpressionTranslator extends SideEffectVisitor { + + private final JavaSource source; + private final VariableAnalyzer analyzer; + private final TypeInfo typeInfo; + + private ExpressionTranslator(JavaSource source, VariableAnalyzer analyzer, TypeInfo typeInfo) { + this.source = source; + this.analyzer = analyzer; + this.typeInfo= typeInfo; + } + + public static void buildExpression(ExpressionNode node, + JavaSource source, + VariableAnalyzer analyzer, + TypeInfo typeInfo) { + ExpressionTranslator builder = new ExpressionTranslator(source, analyzer, typeInfo); + builder.traverse(node); + } + + public void traverse(ExpressionNode node) { + visit(node); + } + + private void visit(ExpressionNode node) { + node.accept(this); + } + + @Override + public void visit(PropertyAccess propertyAccess) { + if (typeInfo.typeOf(propertyAccess.getTarget()) == Type.MAP) { + //Special optimization for maps + visit(propertyAccess.getTarget()); + source.startCall(SourceGenConstants.MAP_GET, true); + visit(propertyAccess.getProperty()); + source.endCall(); + } else { + source.startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, RenderContextImpl.PROPERTY_ACCESS); + visit(propertyAccess.getTarget()); + source.separateArgument(); + visit(propertyAccess.getProperty()); + source.endCall(); + } + } + + @Override + public void visit(Identifier identifier) { + String safeName = analyzer.assignedName(identifier.getName()); + source.append(safeName); + } + + @Override + public void visit(StringConstant text) { + source.stringLiteral(text.getText()); + } + + @Override + public void visit(BinaryOperation binaryOperation) { + BinaryOpGen opGen = Operators.generatorFor(binaryOperation.getOperator()); + source.startExpression(); + opGen.generate(source, this, + typeInfo.getTyped(binaryOperation.getLeftOperand()), + typeInfo.getTyped(binaryOperation.getRightOperand())); + source.endExpression(); + } + + @Override + public void visit(BooleanConstant booleanConstant) { + source.append(Boolean.toString(booleanConstant.getValue())); + } + + @Override + public void visit(NumericConstant numericConstant) { + source.append(numericConstant.getValue().toString()); //todo: check correctness + } + + @Override + public void visit(UnaryOperation unaryOperation) { + UnaryOperator operator = unaryOperation.getOperator(); + ExpressionNode operand = unaryOperation.getTarget(); + UnaryOpGen unaryOpGen = Operators.generatorFor(operator); + source.startExpression(); + unaryOpGen.generate(source, this, typeInfo.getTyped(operand)); + source.endExpression(); + } + + @Override + public void visit(TernaryOperator ternaryOperator) { + GenHelper.generateTernary(source, this, + typeInfo.getTyped(ternaryOperator.getCondition()), + typeInfo.getTyped(ternaryOperator.getThenBranch()), + typeInfo.getTyped(ternaryOperator.getElseBranch())); + } + + @Override + public void visit(RuntimeCall runtimeCall) { + source.startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, SourceGenConstants.RUNTIME_CALL_METHOD) + .stringLiteral(runtimeCall.getFunctionName()); + for (ExpressionNode arg : runtimeCall.getArguments()) { + source.separateArgument(); + visit(arg); + } + source.endCall(); + } + + @Override + public void visit(MapLiteral mapLiteral) { + source.startCall(SourceGenConstants.START_MAP_METHOD).endCall(); + for (Map.Entry<String, ExpressionNode> entry : mapLiteral.getMap().entrySet()) { + source.startCall(SourceGenConstants.MAP_TYPE_ADD, true) + .stringLiteral(entry.getKey()) + .separateArgument(); + visit(entry.getValue()); + source.endCall(); + } + } + + @Override + public void visit(ArrayLiteral arrayLiteral) { + source.startExpression().startArray(); + boolean needsComma = false; + for (ExpressionNode node : arrayLiteral.getItems()) { + if (needsComma) { + source.separateArgument(); + } + visit(node); + needsComma = true; + } + source.endArray().endExpression(); + } + + @Override + public void visit(NullLiteral nullLiteral) { + source.nullLiteral(); + } + + public VariableAnalyzer getAnalyzer() { + return analyzer; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/ExpressionTranslator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/GenHelper.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/GenHelper.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/GenHelper.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/GenHelper.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,112 @@ +/******************************************************************************* + * 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.compiled; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.sling.scripting.sightly.impl.compiled.operator.TypedNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier; +import org.apache.sling.scripting.sightly.impl.compiler.util.expression.SideEffectVisitor; +import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl; + +/** + * Helper for code generation + */ +public class GenHelper { + + public static void generateTernary(JavaSource source, SideEffectVisitor visitor, + TypedNode condition, TypedNode thenBranch, TypedNode elseBranch) { + source.startExpression(); + typeCoercion(source, visitor, condition, Type.BOOLEAN); + source.conditional(); + thenBranch.getNode().accept(visitor); + source.conditionalBranchSep(); + elseBranch.getNode().accept(visitor); + source.endExpression(); + } + + public static void typeCoercion(JavaSource source, SideEffectVisitor visitor, TypedNode node, Type type) { + if (type == node.getType() || type == Type.UNKNOWN) { + node.getNode().accept(visitor); + } else if (type == Type.LONG && node.getType() == Type.DOUBLE) { + callLongCoercion(source, visitor, node.getNode()); + } else { + String coercionMethod = dynamicCoercions.get(type); + if (coercionMethod == null) { + throw new UnsupportedOperationException("Cannot generate coercion to type " + type); + } + callDynamicCoercion(source, visitor, node.getNode(), dynamicCoercions.get(type)); + } + } + + public static void listCoercion(JavaSource source, ExpressionTranslator visitor, TypedNode typedNode) { + ExpressionNode node = typedNode.getNode(); + if (node instanceof Identifier) { + //using list coercion caching optimization + VariableDescriptor descriptor = visitor.getAnalyzer().descriptor(((Identifier) node).getName()); + String listCoercionVar = descriptor.requireListCoercion(); + source.startExpression() + .append(listCoercionVar) + .equality() + .nullLiteral() + .conditional() + .startExpression() + .append(listCoercionVar) + .assign() + .startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, RenderContextImpl.COLLECTION_COERCE); + node.accept(visitor); + source + .endCall() + .endExpression() + .conditionalBranchSep() + .append(listCoercionVar) + .endExpression(); + } else { + source.startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, RenderContextImpl.COLLECTION_COERCE); + typedNode.getNode().accept(visitor); + source.endCall(); + } + } + + private static void callLongCoercion(JavaSource source, SideEffectVisitor visitor, ExpressionNode node) { + source.cast(Type.LONG.getNativeClass()); + source.startExpression(); + node.accept(visitor); + source.endExpression(); + } + + private static void callDynamicCoercion(JavaSource source, SideEffectVisitor visitor, ExpressionNode node, String methodName) { + source.startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, methodName); + node.accept(visitor); + source.endCall(); + } + + private static final Map<Type, String> dynamicCoercions = new HashMap<Type, String>(); + + static { + dynamicCoercions.put(Type.STRING, RenderContextImpl.STRING_COERCE); + dynamicCoercions.put(Type.BOOLEAN, RenderContextImpl.BOOLEAN_COERCE); + dynamicCoercions.put(Type.LONG, RenderContextImpl.NUMERIC_COERCE); + dynamicCoercions.put(Type.DOUBLE, RenderContextImpl.NUMERIC_COERCE); + } + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/GenHelper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaClassBackend.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaClassBackend.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaClassBackend.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaClassBackend.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.compiled; + +import org.apache.sling.scripting.sightly.impl.compiler.CompilerBackend; +import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream; +import org.apache.sling.scripting.sightly.impl.compiler.util.stream.VisitorHandler; +import org.apache.sling.scripting.sightly.impl.compiler.visitor.CodeGenVisitor; +import org.apache.sling.scripting.sightly.impl.compiler.visitor.StatefulVisitor; + +/** + * Backend which generates a Java class. + */ +public class JavaClassBackend implements CompilerBackend { + + private UnitBuilder unitBuilder = new UnitBuilder(); + + @Override + public void handle(CommandStream stream) { + StatefulVisitor statefulVisitor = new StatefulVisitor(); + final CodeGenVisitor visitor = new CodeGenVisitor(unitBuilder, statefulVisitor.getControl()); + statefulVisitor.initializeWith(visitor); + stream.addHandler(new VisitorHandler(statefulVisitor) { + @Override + public void onDone() { + super.onDone(); + visitor.finish(); + } + }); + } + + public CompilationOutput build() { + return this.unitBuilder.build(); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaClassBackend.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaSource.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaSource.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaSource.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaSource.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,264 @@ +/******************************************************************************* + * 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.compiled; + +import org.apache.commons.lang.StringEscapeUtils; + +/** + * Builder object for a Java class printing method. + */ +public class JavaSource { + + private static final String INDENT = " "; + + private int indentLevel; + private final StringBuilder builder = new StringBuilder(); + + public JavaSource prepend(String str) { + builder.insert(0, str); + return this; + } + + public JavaSource beginIf() { + indent().append("if ("); + return this; + } + + public JavaSource completeIf() { + append(") {\n"); + incIndent(); + return this; + } + + public JavaSource endBlock() { + decIndent(); + indent().append("}\n"); + return this; + } + + public JavaSource comment(String text) { + indent().append("//").append(text).append("\n"); + return this; + } + + public JavaSource assign() { + return append(" = "); + } + + public JavaSource number(int value) { + return append(Integer.toString(value)); + } + + public JavaSource increment() { + return append("++"); + } + + public JavaSource beginAssignment(String variable, String type) { + return declare(variable, type).assign(); + } + + public JavaSource beginAssignment(String variable) { + return beginAssignment(variable, "Object"); + } + + public JavaSource declare(String variable, String type) { + return startStatement().append(type).append(" ").append(variable); + } + + public JavaSource declare(String variable) { + return declare(variable, "Object"); + } + + public JavaSource equality() { + return append(" == "); + } + + public JavaSource startCall(String methodName, boolean useDot) { + if (useDot) { + builder.append('.'); + } + builder.append(methodName).append('('); + return this; + } + + public JavaSource startCall(String methodName) { + return startCall(methodName, false); + } + + public JavaSource startMethodCall(String target, String method) { + return append(target).startCall(method, true); + } + + public JavaSource startArray() { + return append("new Object[] {"); + } + + public JavaSource endArray() { + return append("}"); + } + + public JavaSource startStatement() { + indent(); + return this; + } + + public JavaSource nullLiteral() { + return append("null"); + } + + public JavaSource separateArgument() { + builder.append(", "); + return this; + } + + public JavaSource stringLiteral(String text) { + builder.append('"') + .append(StringEscapeUtils.escapeJava(text)) + .append('"'); + return this; + } + + public JavaSource startExpression() { + builder.append('('); + return this; + } + + public JavaSource endExpression() { + builder.append(')'); + return this; + } + + public JavaSource endCall() { + builder.append(')'); + return this; + } + + public JavaSource startBlock() { + indent().append("{\n"); + incIndent(); + return this; + } + + public JavaSource beginFor(String itemVariable, String listVariable) { + startStatement() + .append("for (Object ") + .append(itemVariable) + .append(" : ") + .append(listVariable) + .append(") {\n"); + incIndent(); + return this; + } + + public JavaSource endFor() { + return endBlock(); + } + + public JavaSource endIf() { + return endBlock(); + } + + public JavaSource beginNewInstanceCall(String className) { + return append("new ").append(className).append("("); + } + + public JavaSource append(String str) { + builder.append(str); + return this; + } + + public JavaSource endStatement() { + builder.append(";\n"); + return this; + } + + public JavaSource cast(String type) { + return append("(").append(type).append(")"); + } + + public JavaSource operator(String op) { + return append(" ").append(op).append(" "); + } + + public JavaSource beginAnonymousInstance(String className) { + append("new ").append(className).append("() {\n"); + incIndent(); + return this; + } + + public JavaSource endAnonymousInstance() { + decIndent(); + append("}"); + return this; + } + + public JavaSource beginMethod(String name, String returnType) { + return startStatement().append("public ").append(returnType).append(" ").append(name).append("("); + } + + public JavaSource methodParameter(String name, String type) { + return append(type).append(" ").append(name); + } + + public JavaSource completeMethodSignature() { + append(") {\n"); + incIndent(); + return this; + } + + public JavaSource endMethod() { + return endBlock(); + } + + public JavaSource conditional() { + return append(" ? "); + } + + public JavaSource conditionalBranchSep() { + return append(" : "); + } + + public JavaSource negation() { + return append("!"); + } + + public JavaSource newLine() { + return append("\n"); + } + + private StringBuilder indent() { + for (int i = 0; i < indentLevel; i++) { + builder.append(INDENT); + } + return builder; + } + + private void incIndent() { + indentLevel++; + } + + private void decIndent() { + indentLevel--; + } + + @Override + public String toString() { + return builder.toString(); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/JavaSource.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/SourceGenConstants.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/SourceGenConstants.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/SourceGenConstants.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/SourceGenConstants.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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.compiled; + +/** + * Names related to Java source generation. + */ +public final class SourceGenConstants { + + public static final String OUT_BUFFER = "out"; + + public static final String WRITE_METHOD = "write"; + + public static final String COLLECTION_TYPE = "Collection"; + + public static final String BINDINGS_FIELD = "bindings"; + + public static final String BINDINGS_GET_METHOD = "get"; + + public static final String START_MAP_METHOD = "obj"; + + public static final String MAP_TYPE_ADD = "with"; + + public static final String CALL_UNIT_METHOD = "callUnit"; + + public static final String RENDER_CONTEXT_INSTANCE = "renderContext"; + + public static final String RUNTIME_CALL_METHOD = "call"; + + public static final String COLLECTION_LENGTH_METHOD = "size"; + + public static final String MAP_GET = "get"; + public static final String TRIM_METHOD = "trim"; + public static final String STRING_EMPTY = "isEmpty"; + public static final String OBJ_GET = "get"; + public static final String ARGUMENTS_FIELD = "arguments"; +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/SourceGenConstants.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/Type.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/Type.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/Type.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/Type.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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.compiled; + +/** + * Type inferred for an expression + */ +public enum Type { + UNKNOWN("Object", false), + STRING("String", false), + LONG("long", true), + DOUBLE("double", true), + BOOLEAN("boolean", true), + MAP("java.util.Map", false); + + private final String nativeClass; + private final boolean isPrimitive; + + Type(String nativeClass, boolean isPrimitive) { + this.nativeClass = nativeClass; + this.isPrimitive = isPrimitive; + } + + public String getNativeClass() { + return nativeClass; + } + + public boolean isPrimitive() { + return isPrimitive; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/Type.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInference.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInference.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInference.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInference.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,158 @@ +/******************************************************************************* + * 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.compiled; + +import java.util.IdentityHashMap; +import java.util.Map; + +import org.apache.sling.scripting.sightly.impl.compiled.operator.BinaryOpGen; +import org.apache.sling.scripting.sightly.impl.compiled.operator.Operators; +import org.apache.sling.scripting.sightly.impl.compiled.operator.UnaryOpGen; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.NodeVisitor; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.ArrayLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation; +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.NullLiteral; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant; +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.expression.node.TernaryOperator; +import org.apache.sling.scripting.sightly.impl.compiler.expression.node.UnaryOperation; + +/** + * Expression translator which uses type information + */ +public final class TypeInference implements NodeVisitor<Type> { + + private final VariableAnalyzer analyzer; + private final Map<ExpressionNode, Type> inferMap = new IdentityHashMap<ExpressionNode, Type>(); + + + public static TypeInfo inferTypes(ExpressionNode node, VariableAnalyzer analyzer) { + TypeInference typeInference = new TypeInference(analyzer); + typeInference.infer(node); + return new TypeInfo(typeInference.inferMap); + } + + private TypeInference(VariableAnalyzer analyzer) { + this.analyzer = analyzer; + } + + + + private Type infer(ExpressionNode node) { + Type type = node.accept(this); + inferMap.put(node, type); + return type; + } + + @Override + public Type evaluate(PropertyAccess propertyAccess) { + infer(propertyAccess.getTarget()); + infer(propertyAccess.getProperty()); + return Type.UNKNOWN; + } + + @Override + public Type evaluate(Identifier identifier) { + return analyzer.descriptor(identifier.getName()).getType(); + } + + @Override + public Type evaluate(StringConstant text) { + return Type.STRING; + } + + @Override + public Type evaluate(BinaryOperation binaryOperation) { + Type leftType = infer(binaryOperation.getLeftOperand()); + Type rightType = infer(binaryOperation.getRightOperand()); + BinaryOpGen opGen = Operators.generatorFor(binaryOperation.getOperator()); + return opGen.returnType(leftType, rightType); + } + + @Override + public Type evaluate(BooleanConstant booleanConstant) { + return Type.BOOLEAN; + } + + @Override + public Type evaluate(NumericConstant numericConstant) { + Number number = numericConstant.getValue(); + if (number instanceof Integer || number instanceof Long) { + return Type.LONG; + } + if (number instanceof Float || number instanceof Double) { + return Type.DOUBLE; + } + return Type.UNKNOWN; + } + + @Override + public Type evaluate(UnaryOperation unaryOperation) { + infer(unaryOperation.getTarget()); + UnaryOpGen opGen = Operators.generatorFor(unaryOperation.getOperator()); + return opGen.returnType(infer(unaryOperation.getTarget())); + } + + @Override + public Type evaluate(TernaryOperator ternaryOperator) { + infer(ternaryOperator.getCondition()); + Type thenType = infer(ternaryOperator.getThenBranch()); + Type elseType = infer(ternaryOperator.getElseBranch()); + if (thenType.equals(elseType)) { + return thenType; + } + return Type.UNKNOWN; + } + + @Override + public Type evaluate(RuntimeCall runtimeCall) { + inferAll(runtimeCall.getArguments()); + return Type.UNKNOWN; + } + + @Override + public Type evaluate(MapLiteral mapLiteral) { + inferAll(mapLiteral.getMap().values()); + return Type.MAP; + } + + @Override + public Type evaluate(ArrayLiteral arrayLiteral) { + inferAll(arrayLiteral.getItems()); + return Type.UNKNOWN; + } + + @Override + public Type evaluate(NullLiteral nullLiteral) { + return Type.UNKNOWN; + } + + private void inferAll(Iterable<ExpressionNode> nodes) { + for (ExpressionNode node : nodes) { + infer(node); + } + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInference.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInfo.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInfo.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInfo.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInfo.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.compiled; + +import java.util.Map; + +import org.apache.sling.scripting.sightly.impl.compiled.operator.TypedNode; +import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode; + +/** + * Provide type information for expressions + */ +public class TypeInfo { + + private final Map<ExpressionNode, Type> typeMap; + + public TypeInfo(Map<ExpressionNode, Type> typeMap) { + this.typeMap = typeMap; + } + + public Type typeOf(ExpressionNode node) { + Type type = typeMap.get(node); + if (type == null) { + return Type.UNKNOWN; + } + return type; + } + + public TypedNode getTyped(ExpressionNode expressionNode) { + return new TypedNode(expressionNode, typeOf(expressionNode)); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/TypeInfo.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/UnitBuilder.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/UnitBuilder.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/UnitBuilder.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/UnitBuilder.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.compiled; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Builder for compiled sources + */ +public class UnitBuilder { + + private final JavaSource source = new JavaSource(); + private final Set<String> parameters; + private final Map<String, UnitBuilder> subTemplates = new HashMap<String, UnitBuilder>(); + + public UnitBuilder() { + this(Collections.<String>emptySet()); + } + + public UnitBuilder(Set<String> parameters) { + this.parameters = parameters; + } + + public UnitBuilder newSubBuilder(String name, Set<String> parameters) { + UnitBuilder unitBuilder = new UnitBuilder(parameters); + subTemplates.put(name, unitBuilder); + return unitBuilder; + } + + public JavaSource getSource() { + return source; + } + + public Set<String> getParameters() { + return parameters; + } + + public CompilationOutput build() { + Map<String, CompilationOutput> map = new HashMap<String, CompilationOutput>(); + for (Map.Entry<String, UnitBuilder> entry : subTemplates.entrySet()) { + map.put(entry.getKey(), entry.getValue().build()); + } + return new CompilationOutput(source.toString(), map); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiled/UnitBuilder.java ------------------------------------------------------------------------------ svn:mime-type = text/plain