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

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

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/HomogenousNodeVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/NodeTransformer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/NodeTransformer.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/NodeTransformer.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/NodeTransformer.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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.compiler.util.expression;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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;
+
+public class NodeTransformer implements NodeVisitor<ExpressionNode> {
+
+    public final ExpressionNode transform(ExpressionNode node) {
+        return node.accept(this);
+    }
+
+    @Override
+    public ExpressionNode evaluate(PropertyAccess propertyAccess) {
+        return new PropertyAccess(transform(propertyAccess.getTarget()), transform(propertyAccess.getProperty()));
+    }
+
+    @Override
+    public ExpressionNode evaluate(Identifier identifier) {
+        return identifier;
+    }
+
+    @Override
+    public ExpressionNode evaluate(StringConstant text) {
+        return text;
+    }
+
+    @Override
+    public ExpressionNode evaluate(BinaryOperation binaryOperation) {
+        return new BinaryOperation(binaryOperation.getOperator(),
+                transform(binaryOperation.getLeftOperand()),
+                transform(binaryOperation.getRightOperand()));
+    }
+
+    @Override
+    public ExpressionNode evaluate(BooleanConstant booleanConstant) {
+        return booleanConstant;
+    }
+
+    @Override
+    public ExpressionNode evaluate(NumericConstant numericConstant) {
+        return numericConstant;
+    }
+
+    @Override
+    public ExpressionNode evaluate(UnaryOperation unaryOperation) {
+        return new UnaryOperation(unaryOperation.getOperator(), transform(unaryOperation.getTarget()));
+    }
+
+    @Override
+    public ExpressionNode evaluate(TernaryOperator ternaryOperator) {
+        return new TernaryOperator(
+                transform(ternaryOperator.getCondition()),
+                transform(ternaryOperator.getThenBranch()),
+                transform(ternaryOperator.getElseBranch()));
+    }
+
+    @Override
+    public ExpressionNode evaluate(RuntimeCall runtimeCall) {
+        List<ExpressionNode> children = transformList(runtimeCall.getArguments());
+        return new RuntimeCall(runtimeCall.getFunctionName(), children);
+    }
+
+    @Override
+    public ExpressionNode evaluate(MapLiteral mapLiteral) {
+        HashMap<String, ExpressionNode> map = new HashMap<String, ExpressionNode>();
+        for (Map.Entry<String, ExpressionNode> entry : mapLiteral.getMap().entrySet()) {
+            map.put(entry.getKey(), transform(entry.getValue()));
+        }
+        return new MapLiteral(map);
+    }
+
+    @Override
+    public ExpressionNode evaluate(ArrayLiteral arrayLiteral) {
+        return new ArrayLiteral(transformList(arrayLiteral.getItems()));
+    }
+
+    @Override
+    public ExpressionNode evaluate(NullLiteral nullLiteral) {
+        return nullLiteral;
+    }
+
+    private List<ExpressionNode> transformList(List<ExpressionNode> nodes) {
+        ArrayList<ExpressionNode> result = new ArrayList<ExpressionNode>();
+        for (ExpressionNode node : nodes) {
+            result.add(transform(node));
+        }
+        return result;
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/NodeTransformer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/SideEffectVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/SideEffectVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/SideEffectVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/SideEffectVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * 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.compiler.util.expression;
+
+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 visitor which does not return anything for a node. Instead
+ * it performs specific side-effects depending on the expression node type.
+ */
+public abstract class SideEffectVisitor implements NodeVisitor<Object> {
+
+    public abstract void visit(PropertyAccess propertyAccess);
+
+    public abstract void visit(Identifier identifier);
+
+    public abstract void visit(StringConstant text);
+
+    public abstract void visit(BinaryOperation binaryOperation);
+
+    public abstract void visit(BooleanConstant booleanConstant);
+
+    public abstract void visit(NumericConstant numericConstant);
+
+    public abstract void visit(UnaryOperation unaryOperation);
+
+    public abstract void visit(TernaryOperator ternaryOperator);
+
+    public abstract void visit(RuntimeCall runtimeCall);
+
+    public abstract void visit(MapLiteral mapLiteral);
+
+    public abstract void visit(ArrayLiteral arrayLiteral);
+
+    public abstract void visit(NullLiteral nullLiteral);
+
+    @Override
+    public Object evaluate(PropertyAccess propertyAccess) {
+        visit(propertyAccess);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(Identifier identifier) {
+        visit(identifier);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(StringConstant text) {
+        visit(text);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(BinaryOperation binaryOperation) {
+        visit(binaryOperation);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(BooleanConstant booleanConstant) {
+        visit(booleanConstant);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(NumericConstant numericConstant) {
+        visit(numericConstant);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(UnaryOperation unaryOperation) {
+        visit(unaryOperation);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(TernaryOperator ternaryOperator) {
+        visit(ternaryOperator);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(RuntimeCall runtimeCall) {
+        visit(runtimeCall);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(MapLiteral mapLiteral) {
+        visit(mapLiteral);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(ArrayLiteral arrayLiteral) {
+        visit(arrayLiteral);
+        return null;
+    }
+
+    @Override
+    public Object evaluate(NullLiteral nullLiteral) {
+        visit(nullLiteral);
+        return null;
+    }
+}
+

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/SideEffectVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/BroadcastHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/BroadcastHandler.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/BroadcastHandler.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/BroadcastHandler.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.compiler.util.stream;
+
+import java.util.ArrayList;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandHandler;
+
+/**
+ * Broadcasts commands to other handlers
+ */
+public class BroadcastHandler implements CommandHandler {
+
+    private ArrayList<CommandHandler> handlers = new ArrayList<CommandHandler>();
+
+    /**
+     * Add a new child handler
+     * @param handler - the listening handler
+     */
+    public void addHandler(CommandHandler handler) {
+        handlers.add(handler);
+    }
+
+
+    @Override
+    public void onEmit(Command command) {
+        for (CommandHandler handler : handlers) {
+            handler.onEmit(command);
+        }
+    }
+
+    @Override
+    public void onError(String errorMessage) {
+        for (CommandHandler handler : handlers) {
+            handler.onError(errorMessage);
+        }
+    }
+
+    @Override
+    public void onDone() {
+        for (CommandHandler handler : handlers) {
+            handler.onDone();
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/BroadcastHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/EmitterVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/EmitterVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/EmitterVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/EmitterVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.compiler.util.stream;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Command visitor which writes to an output stream
+ */
+public interface EmitterVisitor extends CommandVisitor {
+
+    /**
+     * Get the output stream
+     * @return - the output stream of this visitor
+     */
+    PushStream getOutputStream();
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/EmitterVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/PushStream.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/PushStream.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/PushStream.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/PushStream.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.util.stream;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandHandler;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+
+/**
+ * A stream that can be written into
+ */
+public class PushStream implements CommandStream {
+
+    private BroadcastHandler handler = new BroadcastHandler();
+    private boolean closed;
+
+    /**
+     * Add a command handler
+     * @param handler - a command handler
+     */
+    @Override
+    public void addHandler(CommandHandler handler) {
+        this.handler.addHandler(handler);
+    }
+
+    /**
+     * Emit the specified command
+     * @param command - the emitted command
+     * @throws UnsupportedOperationException - if the stream is closed
+     */
+    public void emit(Command command) {
+        if (closed) {
+            throw new UnsupportedOperationException("Stream is closed");
+        }
+        this.handler.onEmit(command);
+    }
+
+    /**
+     * Signal an error
+     * @param message - the error message
+     * @throws UnsupportedOperationException - if the stream is already closed
+     */
+    public void signalError(String message) {
+        if (closed) {
+            throw new UnsupportedOperationException("Stream is closed");
+        }
+        closed = true;
+        this.handler.onError(message);
+    }
+
+    /**
+     * Close the stream
+     * @throws UnsupportedOperationException - if the stream is already closed
+     */
+    public void signalDone() {
+        if (closed) {
+            throw new UnsupportedOperationException("Stream is already closed");
+        }
+        closed = true;
+        this.handler.onDone();
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/PushStream.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/ReplayStream.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/ReplayStream.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/ReplayStream.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/ReplayStream.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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.compiler.util.stream;
+
+import java.util.List;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandHandler;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+
+/**
+ * A stream which replays the same commands for all handlers
+ */
+public class ReplayStream implements CommandStream {
+
+    private final List<Command> commands;
+
+    public ReplayStream(List<Command> commands) {
+        this.commands = commands;
+    }
+
+    @Override
+    public void addHandler(CommandHandler handler) {
+        for (Command command : commands) {
+            handler.onEmit(command);
+        }
+        handler.onDone();
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/ReplayStream.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/Streams.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/Streams.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/Streams.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/Streams.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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.compiler.util.stream;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Utility functions for streams
+ */
+public class Streams {
+
+    /**
+     * Attach the visitor as a handle to the inStream and propagate
+     * the done signal from the inStream to the outStream
+     * @param inStream - the input stream
+     * @param outStream - the output stream
+     * @param visitor - a command visitor
+     */
+    public static void connect(CommandStream inStream, final PushStream outStream, CommandVisitor visitor) {
+        inStream.addHandler(new VisitorHandler(visitor) {
+            @Override
+            public void onDone() {
+                outStream.signalDone();
+            }
+        });
+    }
+
+    /**
+     * Attach the emitting visitor to the inStream.
+     * @param inStream - the input stream
+     * @param emitterVisitor - the emitter visitor
+     * @return - the output stream of the emitter
+     */
+    public static CommandStream map(CommandStream inStream, EmitterVisitor emitterVisitor) {
+        PushStream outStream = emitterVisitor.getOutputStream();
+        connect(inStream, outStream, emitterVisitor);
+        return outStream;
+    }
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/Streams.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/VisitorHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/VisitorHandler.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/VisitorHandler.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/VisitorHandler.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.compiler.util.stream;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandHandler;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Delegates commands to a visitor
+ */
+public class VisitorHandler implements CommandHandler {
+
+    private CommandVisitor visitor;
+
+    public VisitorHandler(CommandVisitor visitor) {
+        this.visitor = visitor;
+    }
+
+    @Override
+    public void onEmit(Command command) {
+        command.accept(visitor);
+    }
+
+    @Override
+    public void onError(String errorMessage) {
+        throw new RuntimeException(errorMessage);
+    }
+
+    @Override
+    public void onDone() {
+
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/stream/VisitorHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/CodeGenVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/CodeGenVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/CodeGenVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/CodeGenVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * 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.compiler.visitor;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+
+import org.apache.sling.scripting.sightly.impl.compiled.ExpressionTranslator;
+import org.apache.sling.scripting.sightly.impl.compiled.JavaSource;
+import org.apache.sling.scripting.sightly.impl.compiled.SourceGenConstants;
+import org.apache.sling.scripting.sightly.impl.compiled.Type;
+import org.apache.sling.scripting.sightly.impl.compiled.TypeInference;
+import org.apache.sling.scripting.sightly.impl.compiled.TypeInfo;
+import org.apache.sling.scripting.sightly.impl.compiled.UnitBuilder;
+import org.apache.sling.scripting.sightly.impl.compiled.VariableAnalyzer;
+import org.apache.sling.scripting.sightly.impl.compiled.VariableDescriptor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
+
+/**
+ * Java code generator
+ */
+public class CodeGenVisitor implements CommandVisitor {
+
+    private final JavaSource source;
+    private final UnitBuilder unitBuilder;
+    private final Stack<String> loopStatusStack = new Stack<String>();
+    private final VariableAnalyzer analyzer = new VariableAnalyzer();
+    private final StatefulVisitor.StateControl control;
+    private final Set<String> unitParameters;
+
+    public CodeGenVisitor(UnitBuilder unitBuilder, StatefulVisitor.StateControl control) {
+        this.unitBuilder = unitBuilder;
+        this.source = unitBuilder.getSource();
+        this.control = control;
+        this.unitParameters = new HashSet<String>();
+        for (String param : unitBuilder.getParameters()) {
+            this.unitParameters.add(param.toLowerCase());
+        }
+    }
+
+    /**
+     * Complete building the source
+     */
+    public void finish() {
+        source.prepend(initializations());
+    }
+
+    private String initializations() {
+        JavaSource initSource = new JavaSource();
+        for (VariableDescriptor descriptor : analyzer.allVariables()) {
+            initVariable(descriptor, initSource);
+        }
+        return initSource.toString();
+    }
+
+    private void initVariable(VariableDescriptor descriptor, JavaSource initSource) {
+        switch (descriptor.getScope()) {
+            case DYNAMIC:
+                initSource.beginAssignment(descriptor.getAssignedName());
+                if (descriptor.isTemplateVariable()) {
+                    initSource.startCall(SourceGenConstants.OBJ_GET);
+                } else if (unitParameters.contains(descriptor.getOriginalName().toLowerCase())) {
+                    initSource.startMethodCall(SourceGenConstants.ARGUMENTS_FIELD, SourceGenConstants.BINDINGS_GET_METHOD);
+                } else {
+                    initSource.startMethodCall(SourceGenConstants.BINDINGS_FIELD, SourceGenConstants.BINDINGS_GET_METHOD);
+                }
+                initSource.stringLiteral(descriptor.getOriginalName())
+                        .endCall()
+                        .endStatement();
+                break;
+            case GLOBAL:
+                initSource.beginAssignment(descriptor.getAssignedName())
+                        .nullLiteral()
+                        .endStatement();
+                break;
+        }
+        String listCoercionVar = descriptor.getListCoercion();
+        if (listCoercionVar != null) {
+            //need to initialize the list coercion to null
+            initSource.beginAssignment(listCoercionVar, SourceGenConstants.COLLECTION_TYPE)
+                    .nullLiteral().endStatement();
+        }
+    }
+
+    @Override
+    public void visit(Conditional.Start conditional) {
+        VariableDescriptor descriptor = analyzer.descriptor(conditional.getVariable());
+        boolean negate = !conditional.getExpectedTruthValue();
+        source.beginIf();
+        if (negate) {
+            source.negation();
+        }
+        if (descriptor.getType() == Type.BOOLEAN) {
+            source.append(descriptor.getAssignedName());
+        } else {
+            source.startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, RenderContextImpl.BOOLEAN_COERCE)
+                    .append(descriptor.getAssignedName())
+                    .endCall();
+        }
+        source.completeIf();
+    }
+
+    @Override
+    public void visit(Conditional.End conditionalEnd) {
+        source.endIf();
+    }
+
+    @Override
+    public void visit(VariableBinding.Start variableBinding) {
+        source.startBlock();
+        TypeInfo typeInfo = TypeInference.inferTypes(variableBinding.getExpression(), analyzer);
+        Type type = typeInfo.typeOf(variableBinding.getExpression());
+        String properName = declare(variableBinding.getVariableName(), type);
+        source.beginAssignment(properName, type.getNativeClass());
+        ExpressionTranslator.buildExpression(
+                variableBinding.getExpression(),
+                source,
+                analyzer,
+                typeInfo);
+        source.endStatement();
+    }
+
+    @Override
+    public void visit(VariableBinding.End variableBindingEnd) {
+        VariableDescriptor descriptor = analyzer.endVariable();
+        String listCoercionVar = descriptor.getListCoercion();
+        if (listCoercionVar != null) {
+            //this variable was coerced to list at some point
+            generateCoercionClearing(listCoercionVar);
+        }
+        source.endBlock();
+    }
+
+    @Override
+    public void visit(VariableBinding.Global globalAssignment) {
+        TypeInfo typeInfo = TypeInference.inferTypes(globalAssignment.getExpression(), analyzer);
+        VariableDescriptor descriptor = analyzer.declareGlobal(globalAssignment.getVariableName());
+        String name = descriptor.getAssignedName();
+        source.append(name).assign();
+        ExpressionTranslator.buildExpression(
+                globalAssignment.getExpression(),
+                source,
+                analyzer,
+                typeInfo);
+        source.endStatement();
+        String listCoercionVar = descriptor.getListCoercion();
+        if (listCoercionVar != null) {
+            //variable was used for list coercion. Generating a coercion clearing
+            generateCoercionClearing(listCoercionVar);
+        }
+    }
+
+    @Override
+    public void visit(OutVariable outVariable) {
+        String variable = analyzer.assignedName(outVariable.getVariableName());
+        source.startStatement()
+                .startMethodCall(SourceGenConstants.OUT_BUFFER, SourceGenConstants.WRITE_METHOD)
+                .startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, RenderContextImpl.STRING_COERCE)
+                .append(variable)
+                .endCall()
+                .endCall()
+                .endStatement();
+    }
+
+    @Override
+    public void visit(OutText outText) {
+        source.startStatement()
+                .startMethodCall(SourceGenConstants.OUT_BUFFER, SourceGenConstants.WRITE_METHOD)
+                .stringLiteral(outText.getText())
+                .endCall()
+                .endStatement();
+    }
+
+    @Override
+    public void visit(Loop.Start loop) {
+        VariableDescriptor descriptor = analyzer.descriptor(loop.getListVariable());
+        String listVariable = descriptor.getAssignedName();
+        String collectionVar = descriptor.requireListCoercion();
+        source.beginIf().append(collectionVar).equality().nullLiteral().completeIf()
+                .startStatement()
+                .append(collectionVar)
+                .assign()
+                .startMethodCall(SourceGenConstants.RENDER_CONTEXT_INSTANCE, RenderContextImpl.COLLECTION_COERCE)
+                .append(listVariable)
+                .endCall()
+                .endStatement()
+                .endIf();
+        String indexVar = declare(loop.getIndexVariable(), Type.LONG);
+        source.beginAssignment(indexVar, Type.LONG.getNativeClass()).number(0).endStatement();
+        String itemVar = declare(loop.getItemVariable(), Type.UNKNOWN);
+        source.beginFor(itemVar, collectionVar);
+        loopStatusStack.push(indexVar);
+    }
+
+    @Override
+    public void visit(Loop.End loopEnd) {
+        String indexVar = loopStatusStack.pop();
+        source.startStatement().append(indexVar).increment().endStatement();
+        source.endFor();
+        analyzer.endVariable();
+        analyzer.endVariable();
+    }
+
+    @Override
+    public void visit(Procedure.Start startProcedure) {
+        UnitBuilder subTemplateUnit = unitBuilder.newSubBuilder(startProcedure.getName(), startProcedure.getParameters());
+        analyzer.declareTemplate(startProcedure.getName());
+        control.push(new CodeGenVisitor(subTemplateUnit, control));
+    }
+
+    @Override
+    public void visit(Procedure.End endProcedure) {
+        CodeGenVisitor previous = (CodeGenVisitor) control.pop();
+        previous.finish();
+    }
+
+    @Override
+    public void visit(Procedure.Call procedureCall) {
+        String templateVar = analyzer.assignedName(procedureCall.getTemplateVariable());
+        String argVar = analyzer.assignedName(procedureCall.getArgumentsVariable());
+        source.startStatement()
+                .startCall(SourceGenConstants.CALL_UNIT_METHOD, false)
+                .append(SourceGenConstants.RENDER_CONTEXT_INSTANCE)
+                .separateArgument()
+                .append(templateVar)
+                .separateArgument()
+                .append(argVar)
+                .endCall()
+                .endStatement();
+    }
+
+    private String declare(String originalName, Type type) {
+        return analyzer.declareVariable(originalName, type).getAssignedName();
+    }
+
+    private void generateCoercionClearing(String coercionVariableName) {
+        source.startStatement().append(coercionVariableName).assign().nullLiteral().endStatement();
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/CodeGenVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/IgnoreRange.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/IgnoreRange.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/IgnoreRange.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/IgnoreRange.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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.compiler.visitor;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+
+/**
+ * Ignore a nested range of commands
+ */
+public abstract class IgnoreRange extends UniformVisitor {
+
+    private final Class<? extends Command> rangeStart;
+    private final Class<? extends Command> rangeEnd;
+
+    private int skipCount = 1;
+
+    public IgnoreRange(Class<? extends Command> rangeStart, Class<? extends Command> rangeEnd) {
+        this.rangeStart = rangeStart;
+        this.rangeEnd = rangeEnd;
+    }
+
+    @Override
+    public void onCommand(Command command) {
+        Class<? extends Command> commandClass = command.getClass();
+        if (commandClass.equals(rangeStart)) {
+            skipCount++;
+        } else if (commandClass.equals(rangeEnd)) {
+            skipCount--;
+        }
+        if (skipCount == 0) {
+            onCompleted();
+        }
+    }
+
+    protected abstract void onCompleted();
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/IgnoreRange.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulRangeIgnore.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulRangeIgnore.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulRangeIgnore.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulRangeIgnore.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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.compiler.visitor;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+
+/**
+ * Variant of {@link IgnoreRange} to be used in stateful visitors.
+ */
+public class StatefulRangeIgnore extends IgnoreRange {
+
+    private final StatefulVisitor.StateControl stateControl;
+
+    public StatefulRangeIgnore(StatefulVisitor.StateControl stateControl, Class<? extends Command> rangeStart,
+                               Class<? extends Command> rangeEnd) {
+        super(rangeStart, rangeEnd);
+        this.stateControl = stateControl;
+    }
+
+    @Override
+    protected void onCompleted() {
+        stateControl.pop();
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulRangeIgnore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * 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.compiler.visitor;
+
+import java.util.Stack;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+
+/**
+ * Implements the state pattern for command visitors
+ */
+public class StatefulVisitor implements CommandVisitor {
+
+    private final Stack<CommandVisitor> stack = new Stack<CommandVisitor>();
+    private CommandVisitor visitor;
+    private StateControl control = new StateControl();
+
+    public StatefulVisitor() {
+        this.visitor = InvalidState.INSTANCE;
+    }
+
+    public StateControl getControl() {
+        return control;
+    }
+
+    public void initializeWith(CommandVisitor initialState) {
+        if (this.visitor != InvalidState.INSTANCE) {
+            throw new IllegalStateException("Initial state is already set");
+        }
+        this.visitor = initialState;
+    }
+
+    @Override
+    public void visit(Conditional.Start conditionalStart) {
+        visitor.visit(conditionalStart);
+    }
+
+    @Override
+    public void visit(Conditional.End conditionalEnd) {
+        visitor.visit(conditionalEnd);
+    }
+
+    @Override
+    public void visit(VariableBinding.Start variableBindingStart) {
+        visitor.visit(variableBindingStart);
+    }
+
+    @Override
+    public void visit(VariableBinding.End variableBindingEnd) {
+        visitor.visit(variableBindingEnd);
+    }
+
+    @Override
+    public void visit(VariableBinding.Global globalAssignment) {
+        visitor.visit(globalAssignment);
+    }
+
+    @Override
+    public void visit(OutVariable outVariable) {
+        visitor.visit(outVariable);
+    }
+
+    @Override
+    public void visit(OutText outText) {
+        visitor.visit(outText);
+    }
+
+    @Override
+    public void visit(Loop.Start loopStart) {
+        visitor.visit(loopStart);
+    }
+
+    @Override
+    public void visit(Loop.End loopEnd) {
+        visitor.visit(loopEnd);
+    }
+
+    @Override
+    public void visit(Procedure.Start startProcedure) {
+        visitor.visit(startProcedure);
+    }
+
+    @Override
+    public void visit(Procedure.End endProcedure) {
+        visitor.visit(endProcedure);
+    }
+
+    @Override
+    public void visit(Procedure.Call procedureCall) {
+        visitor.visit(procedureCall);
+    }
+
+    private void pushVisitor(CommandVisitor visitor) {
+        stack.push(this.visitor);
+        this.visitor = visitor;
+    }
+
+    private CommandVisitor popVisitor() {
+        CommandVisitor top = this.visitor;
+        this.visitor = this.stack.pop();
+        return top;
+    }
+
+    public final class StateControl {
+
+        public void push(CommandVisitor visitor) {
+            pushVisitor(visitor);
+        }
+
+        public CommandVisitor pop() {
+            return popVisitor();
+        }
+
+        public CommandVisitor replace(CommandVisitor visitor) {
+            CommandVisitor current = pop();
+            push(visitor);
+            return current;
+        }
+    }
+
+    private static final class InvalidState extends UniformVisitor {
+
+        public static final InvalidState INSTANCE = new InvalidState();
+
+        private InvalidState() {
+        }
+
+        @Override
+        public void onCommand(Command command) {
+            throw new IllegalStateException("StatefulVisitor has not been initialized");
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/StatefulVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.visitor;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.impl.compiler.util.VariableTracker;
+
+/**
+ * Command visitor which tracks variables in commands
+ */
+public abstract class TrackingVisitor<T> extends UniformVisitor {
+
+    protected final VariableTracker<T> tracker = new VariableTracker<T>();
+
+    @Override
+    public void visit(VariableBinding.Start variableBindingStart) {
+        super.visit(variableBindingStart);
+        tracker.pushVariable(variableBindingStart.getVariableName(), assignDefault(variableBindingStart));
+    }
+
+    @Override
+    public void visit(VariableBinding.End variableBindingEnd) {
+        super.visit(variableBindingEnd);
+        tracker.popVariable();
+    }
+
+    @Override
+    public void visit(Loop.Start loopStart) {
+        super.visit(loopStart);
+        tracker.pushVariable(loopStart.getIndexVariable(), assignDefault(loopStart));
+        tracker.pushVariable(loopStart.getItemVariable(), assignDefault(loopStart));
+    }
+
+    @Override
+    public void visit(Loop.End loopEnd) {
+        super.visit(loopEnd);
+        tracker.popVariable();
+        tracker.popVariable();
+    }
+
+    protected abstract T assignDefault(Command command);
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/UniformVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/UniformVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/UniformVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/UniformVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.compiler.visitor;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+
+/**
+ * Do not dispatch for different command types
+ */
+public abstract class UniformVisitor implements CommandVisitor {
+
+    protected abstract void onCommand(Command command);
+
+    @Override
+    public void visit(Conditional.Start conditionalStart) {
+        onCommand(conditionalStart);
+    }
+
+    @Override
+    public void visit(Conditional.End conditionalEnd) {
+        onCommand(conditionalEnd);
+    }
+
+    @Override
+    public void visit(VariableBinding.Start variableBindingStart) {
+        onCommand(variableBindingStart);
+    }
+
+    @Override
+    public void visit(VariableBinding.End variableBindingEnd) {
+        onCommand(variableBindingEnd);
+    }
+
+    @Override
+    public void visit(VariableBinding.Global globalAssignment) {
+        onCommand(globalAssignment);
+    }
+
+    @Override
+    public void visit(OutVariable outVariable) {
+        onCommand(outVariable);
+    }
+
+    @Override
+    public void visit(OutText outText) {
+        onCommand(outText);
+    }
+
+    @Override
+    public void visit(Loop.Start loopStart) {
+        onCommand(loopStart);
+    }
+
+    @Override
+    public void visit(Loop.End loopEnd) {
+        onCommand(loopEnd);
+    }
+
+    @Override
+    public void visit(Procedure.Start startProcedure) {
+        onCommand(startProcedure);
+    }
+
+    @Override
+    public void visit(Procedure.End endProcedure) {
+        onCommand(endProcedure);
+    }
+
+    @Override
+    public void visit(Procedure.Call procedureCall) {
+        onCommand(procedureCall);
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/UniformVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/ExtensionRegistryService.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/ExtensionRegistryService.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/ExtensionRegistryService.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/ExtensionRegistryService.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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.engine;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
+import org.osgi.framework.Constants;
+
+/**
+ * Aggregator for all runtime extensions.
+ */
+@Component
+@Service(ExtensionRegistryService.class)
+@Reference(
+        policy = ReferencePolicy.DYNAMIC,
+        referenceInterface = RuntimeExtension.class,
+        name = "extensionService",
+        cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE
+)
+public class ExtensionRegistryService {
+
+    private volatile Map<String, RuntimeExtension> mapping = new HashMap<String, RuntimeExtension>();
+    private Map<String, Integer> mappingPriorities = new HashMap<String, Integer>(10, 0.9f);
+
+    public Map<String, RuntimeExtension> extensions() {
+        return mapping;
+    }
+
+    @SuppressWarnings("UnusedDeclaration")
+    protected synchronized void bindExtensionService(RuntimeExtension extension, Map<String, Object> properties) {
+        Integer newPriority = PropertiesUtil.toInteger(properties.get(Constants.SERVICE_RANKING), 0);
+        String extensionName = PropertiesUtil.toString(properties.get(RuntimeExtension.SCR_PROP_NAME), "");
+        Integer priority = PropertiesUtil.toInteger(mappingPriorities.get(extensionName), 0);
+        if (newPriority > priority) {
+                mapping = Collections.unmodifiableMap(add(mapping, extension, extensionName));
+                mappingPriorities.put(extensionName, newPriority);
+        } else {
+            if (!mapping.containsKey(extensionName)) {
+                mapping = Collections.unmodifiableMap(add(mapping, extension, extensionName));
+                mappingPriorities.put(extensionName, newPriority);
+            }
+        }
+
+    }
+
+    @SuppressWarnings("UnusedDeclaration")
+    protected synchronized void unbindExtensionService(RuntimeExtension extension, Map<String, Object> properties) {
+        String extensionName = PropertiesUtil.toString(properties.get(RuntimeExtension.SCR_PROP_NAME), "");
+        mappingPriorities.remove(extensionName);
+        mapping = Collections.unmodifiableMap(remove(mapping, extensionName));
+    }
+
+    private Map<String, RuntimeExtension> add(Map<String, RuntimeExtension> oldMap, RuntimeExtension extension, String extensionName) {
+        HashMap<String, RuntimeExtension> newMap = new HashMap<String, RuntimeExtension>(oldMap);
+        newMap.put(extensionName, extension);
+        return newMap;
+    }
+
+    private Map<String, RuntimeExtension> remove(Map<String, RuntimeExtension> oldMap, String extensionName) {
+        HashMap<String, RuntimeExtension> newMap = new HashMap<String, RuntimeExtension>(oldMap);
+        newMap.remove(extensionName);
+        return newMap;
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/ExtensionRegistryService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyBindingsValuesProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyBindingsValuesProvider.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyBindingsValuesProvider.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyBindingsValuesProvider.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.engine;
+
+import javax.script.Bindings;
+
+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.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.scripting.api.BindingsValuesProvider;
+
+/**
+ * Sightly specific {@code BindingsValuesProvider}.
+ */
+@Component()
+@Service(BindingsValuesProvider.class)
+@Properties({
+        @Property(name = "javax.script.name", value = "sightly", propertyPrivate = true)
+})
+public class SightlyBindingsValuesProvider implements BindingsValuesProvider {
+
+    public static final String PROPERTIES = "properties";
+
+    @Override
+    public void addBindings(Bindings bindings) {
+        if (!bindings.containsKey(PROPERTIES)) {
+            Resource currentResource = (Resource) bindings.get(SlingBindings.RESOURCE);
+            if (currentResource != null) {
+                bindings.put(PROPERTIES, currentResource.adaptTo(ValueMap.class));
+            }
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyBindingsValuesProvider.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyEngineConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyEngineConfiguration.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyEngineConfiguration.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyEngineConfiguration.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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.engine;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+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.commons.osgi.PropertiesUtil;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * Holds various Sightly engine global configurations.
+ */
+@Component(
+        metatype = true,
+        label = "Apache Sling Scripting Sightly Engine Configuration",
+        description = "Sightly Engine Configuration Options"
+)
+@Service(SightlyEngineConfiguration.class)
+@Properties({
+        @Property(
+                name = SightlyEngineConfiguration.SCR_PROP_NAME_DEVMODE,
+                boolValue = SightlyEngineConfiguration.SCR_PROP_DEFAULT_DEVMODE,
+                label = "Development Mode",
+                description = "If enabled, Sightly components will be recompiled at every request instead of loading objects from memory."
+        ),
+        @Property(
+                name = SightlyEngineConfiguration.SCR_PROP_NAME_ENCODING,
+                value = SightlyEngineConfiguration.SCR_PROP_DEFAULT_ENCODING,
+                label = "Template Files Default Encoding",
+                description = "The default encoding used for reading Sightly template files (this directly affects how Sightly templates" +
+                        "are rendered)."
+        )
+})
+public class SightlyEngineConfiguration {
+
+    public static final String SCR_PROP_NAME_DEVMODE = "org.apache.sling.scripting.sightly.devmode";
+    public static final boolean SCR_PROP_DEFAULT_DEVMODE = false;
+
+    public static final String SCR_PROP_NAME_ENCODING = "org.apache.sling.scripting.sightly.encoding";
+    public static final String SCR_PROP_DEFAULT_ENCODING = "UTF-8";
+
+    private String engineVersion = "0";
+    private boolean devMode = false;
+    private String encoding = SCR_PROP_DEFAULT_ENCODING;
+
+    public String getEngineVersion() {
+        return engineVersion;
+    }
+
+    public boolean isDevMode() {
+        return devMode;
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    protected void activate(ComponentContext componentContext) {
+        InputStream ins = null;
+        try {
+            ins = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
+            if (ins != null) {
+                Manifest manifest = new Manifest(ins);
+                Attributes attrs = manifest.getMainAttributes();
+                String version = attrs.getValue("ScriptEngine-Version");
+                if (version != null) {
+                    engineVersion = version;
+                }
+            }
+        } catch (IOException ioe) {
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+        Dictionary properties = componentContext.getProperties();
+        devMode = PropertiesUtil.toBoolean(properties.get(SCR_PROP_NAME_DEVMODE), SCR_PROP_DEFAULT_DEVMODE);
+        encoding = PropertiesUtil.toString(properties.get(SCR_PROP_NAME_ENCODING), SCR_PROP_DEFAULT_ENCODING);
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyEngineConfiguration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.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.engine;
+
+import java.io.Reader;
+import java.util.Collections;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.commons.classloader.DynamicClassLoader;
+import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
+import org.apache.sling.scripting.sightly.SightlyException;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Sightly Script engine
+ */
+public class SightlyScriptEngine extends AbstractSlingScriptEngine {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SightlyScriptEngine.class);
+    private static final Bindings EMPTY_BINDINGS = new SimpleBindings(Collections.<String, Object>emptyMap());
+    private static final int MAX_CLASSLOADER_RETRIES = 5;
+
+    private final UnitLoader unitLoader;
+    private final ExtensionRegistryService extensionRegistryService;
+
+    public SightlyScriptEngine(ScriptEngineFactory scriptEngineFactory,
+                               UnitLoader unitLoader,
+                               ExtensionRegistryService extensionRegistryService) {
+        super(scriptEngineFactory);
+        this.unitLoader = unitLoader;
+        this.extensionRegistryService = extensionRegistryService;
+    }
+
+    @Override
+    public Object eval(Reader reader, ScriptContext scriptContext) throws ScriptException {
+        ClassLoader old = Thread.currentThread().getContextClassLoader();
+        Thread.currentThread().setContextClassLoader(((SightlyScriptEngineFactory) getFactory()).getClassLoader());
+        checkArguments(reader, scriptContext);
+        Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+        SlingScriptHelper slingScriptHelper = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
+        Resource scriptResource = slingScriptHelper.getScript().getScriptResource();
+
+        final SlingBindings slingBindings = new SlingBindings();
+        slingBindings.putAll(bindings);
+
+        Bindings globalBindings = new SimpleBindings(slingBindings);
+
+        final SlingHttpServletRequest request = slingBindings.getRequest();
+        final Object oldValue = request.getAttribute(SlingBindings.class.getName());
+        try {
+            request.setAttribute(SlingBindings.class.getName(), slingBindings);
+            evaluateScript(scriptResource, globalBindings);
+        } finally {
+            request.setAttribute(SlingBindings.class.getName(), oldValue);
+            Thread.currentThread().setContextClassLoader(old);
+        }
+
+        return null;
+    }
+
+    private void evaluateScript(Resource scriptResource, Bindings bindings) {
+        ResourceResolver resourceResolver = null;
+        RenderContextImpl renderContext = new RenderContextImpl(bindings, extensionRegistryService.extensions());
+        RenderUnit renderUnit = unitLoader.createUnit(scriptResource, bindings, renderContext);
+        try {
+            resourceResolver = getAdminResourceResolver(bindings);
+            renderUnit.render(renderContext, EMPTY_BINDINGS);
+        } catch (NoClassDefFoundError defFoundError) {
+            if (renderContext != null) {
+                ClassLoader dcl = renderUnit.getClass().getClassLoader().getParent();
+                if (dcl instanceof DynamicClassLoader && !((DynamicClassLoader) dcl).isLive()) {
+                    boolean defError = true;
+                    int retries = 0;
+                    while (defError) {
+                        try {
+                            renderUnit = unitLoader.createUnit(scriptResource, bindings, renderContext);
+                            renderUnit.render(renderContext, EMPTY_BINDINGS);
+                            defError = false;
+                        } catch (Throwable t) {
+                            if (!(t instanceof NoClassDefFoundError)) {
+                                // break immediately if there's a different error than a classloader one
+                                if (t instanceof Error) {
+                                    throw (Error) t;
+                                }
+                                throw (RuntimeException) t;
+                            }
+                            retries++;
+                            if (retries > MAX_CLASSLOADER_RETRIES) {
+                                LOG.error("Max number of retries (" + MAX_CLASSLOADER_RETRIES +
+                                        ") for obtaining a valid RenderUnit was exceeded.");
+                                throw defFoundError;
+                            }
+                        }
+                    }
+                } else {
+                    // if we can't recover from this just throw the original exception
+                    throw defFoundError;
+                }
+            }
+        }
+        finally {
+            if (resourceResolver != null) {
+                resourceResolver.close();
+            }
+        }
+    }
+
+    private void checkArguments(Reader reader, ScriptContext scriptContext) {
+        if (reader == null) {
+            throw new NullPointerException("Reader cannot be null");
+        }
+        if (scriptContext == null) {
+            throw new NullPointerException("ScriptContext cannot be null");
+        }
+    }
+
+    private ResourceResolver getAdminResourceResolver(Bindings bindings) {
+        SlingScriptHelper sling = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
+        ResourceResolverFactory rrf = sling.getService(ResourceResolverFactory.class);
+        try {
+            return rrf.getAdministrativeResourceResolver(null);
+        } catch (LoginException e) {
+            throw new SightlyException(e);
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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.engine;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+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.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
+import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
+
+/**
+ * Sightly template engine factory
+ */
+@Component()
+@Service(ScriptEngineFactory.class)
+@Properties({
+        @Property(name = "service.description", value = "Sightly Templating Engine"),
+        @Property(name = "compatible.javax.script.name", value = "sly")
+})
+public class SightlyScriptEngineFactory extends AbstractScriptEngineFactory {
+
+    @Reference
+    private UnitLoader unitLoader = null;
+
+    @Reference
+    private ExtensionRegistryService extensionRegistryService = null;
+
+    @Reference()
+    private DynamicClassLoaderManager dynamicClassLoaderManager;
+
+    private ClassLoader dynamicClassLoader;
+
+    public final static String SHORT_NAME = "sightly";
+
+    public final static String LANGUAGE_NAME = "The Sightly Templating Language";
+
+    public final static String LANGUAGE_VERSION = "1.0";
+
+    public final static String EXTENSION = "html";
+
+    public SightlyScriptEngineFactory() {
+        setNames(SHORT_NAME);
+        setExtensions(EXTENSION);
+    }
+
+    @Override
+    public String getLanguageName() {
+        return LANGUAGE_NAME;
+    }
+
+    @Override
+    public String getLanguageVersion() {
+        return LANGUAGE_VERSION;
+    }
+
+    @Override
+    public ScriptEngine getScriptEngine() {
+        return new SightlyScriptEngine(this, unitLoader, extensionRegistryService);
+    }
+
+    protected void bindDynamicClassLoaderManager(final DynamicClassLoaderManager dclm) {
+        if (this.dynamicClassLoader != null) {
+            this.dynamicClassLoader = null;
+            this.dynamicClassLoaderManager = null;
+        }
+        this.dynamicClassLoaderManager = dclm;
+        dynamicClassLoader = dclm.getDynamicClassLoader();
+    }
+
+    protected void unbindDynamicClassLoaderManager(final DynamicClassLoaderManager dclm) {
+        if (this.dynamicClassLoaderManager == dclm) {
+            this.dynamicClassLoader = null;
+            this.dynamicClassLoaderManager = null;
+        }
+    }
+
+    protected ClassLoader getClassLoader() {
+        return dynamicClassLoader;
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain