Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/Use.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/Use.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/Use.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/Use.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.pojo; + +import javax.script.Bindings; + +import aQute.bnd.annotation.ConsumerType; + +/** + * The <code>Use</code> interface can be implemented by Java objects + * which are instantiated as part of processing {@code data-sly-use} + * attributes. + * + * @see <a href="http://docs.adobe.com/docs/en/aem/6-0/develop/sightly.html#use">Sightly Block Statements - Use</a> + */ +@ConsumerType +public interface Use { + + /** + * Called to initialize the Java object with the current Java Scripting + * API bindings. + * <p> + * This method is called only if the object has been instantiated by + * Sightly as part of processing the {@code data-sly-use} attribute. + * <p> + * The Java Scripting API bindings provide all the global variables + * known to a script being executed. Consider these bindings of a map + * from variable name to the variable's value. + * + * @param bindings The Java Scripting API bindings. + */ + public void init(Bindings bindings); + +}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/Use.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/package-info.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/package-info.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/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.pojo; + +import aQute.bnd.annotation.Version; Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/pojo/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/RenderContext.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/RenderContext.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/RenderContext.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/RenderContext.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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.render; + +import java.util.Collection; +import java.util.Map; + +import javax.script.Bindings; + +import org.apache.sling.scripting.sightly.extension.ExtensionInstance; +import org.apache.sling.scripting.sightly.extension.RuntimeExtension; +import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit; + +import aQute.bnd.annotation.ProviderType; + +/** + * The {@code RenderContext} defines the context for executing Sightly scripts (see {@link RenderUnit}). + */ +@ProviderType +public interface RenderContext { + + /** + * Returns the map of script bindings available to Sightly scripts. + * + * @return the global bindings for a script + */ + Bindings getBindings(); + + /** + * Call one of the registered {@link RuntimeExtension}s. + * + * @param functionName the name under which the extension is registered + * @param arguments the extension's arguments + * @return the {@link ExtensionInstance}'s result + */ + Object call(String functionName, Object... arguments); + + /** + * Retrieve the specified property from the given object + * + * @param target - the target object + * @param property - the property name + * @return - the value of the property or null if the object has no such property + */ + Object resolveProperty(Object target, Object property); + + /** + * Convert the given object to a string. + * + * @param target - the target object + * @return - the string representation of the object + */ + String toString(Object target); + + /** + * Convert the given object to a boolean value + * + * @param object - the target object + * @return - the boolean representation of that object + */ + boolean toBoolean(Object object); + + /** + * Coerce the object to a numeric value + * + * @param object - the target object + * @return - the numeric representation + */ + Number toNumber(Object object); + + boolean isCollection(Object obj); + + /** + * Force the conversion of the object to a collection + * + * @param object - the target object + * @return the collection representation of the object + */ + Collection<Object> toCollection(Object object); + + /** + * Force the conversion of the target object to a map + * + * @param object - the target object + * @return - a map representation of the object. Default is an empty map + */ + Map toMap(Object object); + +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/RenderContext.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/package-info.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/package-info.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/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.render; + +import aQute.bnd.annotation.Version; Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/render/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.use; + +/** + * Result returned by a use provider + */ +public final class ProviderOutcome { + + private boolean success; + private Object result; + + private static final ProviderOutcome FAILURE = new ProviderOutcome(false, null); + + /** + * Create a successful outcome + * @param result the result + * @return a successful result + */ + public static ProviderOutcome success(Object result) { + return new ProviderOutcome(true, result); + } + + /** + * Create a failed outcome + * @return a failed outcome + */ + public static ProviderOutcome failure() { + return FAILURE; + } + + /** + * If the given obj is not null return a successful outcome, with the given result. + * Otherwise, return failure + * @param obj the result + * @return an outcome based on whether the parameter is null or not + */ + public static ProviderOutcome notNullOrFailure(Object obj) { + return (obj == null) ? failure() : success(obj); + } + + private ProviderOutcome(boolean success, Object result) { + this.success = success; + this.result = result; + } + + /** + * Check if the outcome has been successful + * @return the outcome success status + */ + public boolean isSuccess() { + return success; + } + + /** + * Check whether the outcome is a failure + * @return the outcome failure status + */ + public boolean isFailure() { + return !isSuccess(); + } + + /** + * Get the result in this outcome + * + * @return the result of the container + * @throws java.lang.UnsupportedOperationException if the outcome is a failure + */ + public Object getResult() { + if (!success) { + throw new UnsupportedOperationException("Outcome has not been successful"); + } + return result; + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/SightlyUseException.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/SightlyUseException.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/SightlyUseException.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/SightlyUseException.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.use; + +import org.apache.sling.scripting.sightly.SightlyException; + +/** + * Exception raised by the use resolving mechanism + */ +public class SightlyUseException extends SightlyException { + public SightlyUseException() { + } + + public SightlyUseException(String message) { + super(message); + } + + public SightlyUseException(String message, Throwable cause) { + super(message, cause); + } + + public SightlyUseException(Throwable cause) { + super(cause); + } +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/SightlyUseException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/UseProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/UseProvider.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/UseProvider.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/UseProvider.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.use; + +import javax.script.Bindings; + +import org.apache.sling.scripting.sightly.render.RenderContext; + +import aQute.bnd.annotation.ConsumerType; + +/** + * Provides instances for the use API. Providers are tried in the order + * of their priority until one is found which can provide a non-null instance + */ +@ConsumerType +public interface UseProvider { + + /** + * Provide an instance based on the given identifier + * @param identifier the identifier of the dependency + * @param renderContext the current rendering context + * @param arguments Specific arguments provided by the use plugin + * @return a container with the instance that corresponds to the identifier. If the identifier cannot be + * handled by this provider, a failed outcome is returned + */ + ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments); +} Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/UseProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/package-info.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/package-info.java (added) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/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.use; + +import aQute.bnd.annotation.Version; Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/compiled_unit_template.txt URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/compiled_unit_template.txt?rev=1642281&r1=1642280&r2=1642281&view=diff ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/compiled_unit_template.txt (original) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/compiled_unit_template.txt Fri Nov 28 10:18:01 2014 @@ -18,24 +18,20 @@ ******************************************************************************/ package ##PackageName##; +import java.io.PrintWriter; import java.util.Collection; import javax.script.Bindings; -import org.apache.sling.scripting.sightly.api.ObjectModel; -import org.apache.sling.scripting.sightly.api.StackedWriter; -import org.apache.sling.scripting.sightly.api.SightlyRuntime; -import org.apache.sling.scripting.sightly.api.BaseRenderUnit; -import org.apache.sling.scripting.sightly.api.RenderContext; +import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit; +import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl; -public final class ##ClassName## extends BaseRenderUnit { +public final class ##ClassName## extends RenderUnit { @Override - protected final void render(StackedWriter out, + protected final void render(PrintWriter out, Bindings bindings, Bindings arguments, - ObjectModel objectModel, - SightlyRuntime runtime, - RenderContext renderContext) { + RenderContextImpl renderContext) { // Main Template Body ----------------------------------------------------------------------------- ##MainBody## Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/subtemplate.txt URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/subtemplate.txt?rev=1642281&r1=1642280&r2=1642281&view=diff ============================================================================== --- sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/subtemplate.txt (original) +++ sling/trunk/contrib/scripting/sightly/engine/src/main/resources/templates/subtemplate.txt Fri Nov 28 10:18:01 2014 @@ -16,15 +16,13 @@ * specific language governing permissions and limitations * under the License. ******************************************************************************/ -addSubTemplate("##Name##", new BaseRenderUnit() { +addSubTemplate("##Name##", new RenderUnit() { @Override - protected final void render(StackedWriter out, + protected final void render(PrintWriter out, Bindings bindings, Bindings arguments, - ObjectModel objectModel, - SightlyRuntime runtime, - RenderContext renderContext) { + RenderContextImpl renderContext) { // Main Sub-Template Body ------------------------------------------------------------------------- ##MainBody## Modified: sling/trunk/contrib/scripting/sightly/js-use-provider/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/pom.xml?rev=1642281&r1=1642280&r2=1642281&view=diff ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/pom.xml (original) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/pom.xml Fri Nov 28 10:18:01 2014 @@ -79,11 +79,18 @@ <!-- D E P E N D E N C I E S --> <!-- ======================================================================= --> <dependencies> + <!-- OSGI --> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <scope>provided</scope> </dependency> + <!-- Sling --> <dependency> <groupId>org.apache.sling</groupId> Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Console.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Console.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Console.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Console.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.js.impl; + +import org.slf4j.Logger; + +/** + * The console object, used for logging + */ +public class Console { + + private final Logger logger; + + public Console(Logger logger) { + this.logger = logger; + } + + public void log(String msg) { + logger.info(msg); + } + + public void warn(String msg) { + logger.warn(msg); + } + + public void error(String msg) { + logger.error(msg); + } + + public void debug(String msg) { + logger.debug(msg); + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Console.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsEnvironment.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsEnvironment.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsEnvironment.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsEnvironment.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,173 @@ +/******************************************************************************* + * 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.js.impl; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import javax.script.SimpleBindings; +import javax.script.SimpleScriptContext; + +import org.apache.commons.io.IOUtils; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.scripting.sightly.ResourceResolution; +import org.mozilla.javascript.Context; +import org.slf4j.LoggerFactory; +import org.apache.sling.scripting.sightly.js.impl.async.AsyncContainer; +import org.apache.sling.scripting.sightly.js.impl.async.TimingBindingsValuesProvider; +import org.apache.sling.scripting.sightly.js.impl.async.UnaryCallback; +import org.apache.sling.scripting.sightly.js.impl.cjs.CommonJsModule; +import org.apache.sling.scripting.sightly.js.impl.loop.EventLoop; +import org.apache.sling.scripting.sightly.js.impl.loop.EventLoopInterop; +import org.apache.sling.scripting.sightly.js.impl.loop.Task; +import org.apache.sling.scripting.sightly.js.impl.use.DependencyResolver; +import org.apache.sling.scripting.sightly.js.impl.use.UseFunction; +import org.apache.sling.scripting.sightly.use.SightlyUseException; + +/** + * Environment for running JS scripts + */ +public class JsEnvironment { + + private final ScriptEngine jsEngine; + private final Bindings engineBindings; + private EventLoop eventLoop; + + public JsEnvironment(ScriptEngine jsEngine) { + this.jsEngine = jsEngine; + engineBindings = new SimpleBindings(); + TimingBindingsValuesProvider.INSTANCE.addBindings(engineBindings); + } + + public void initialize() { + Context context = Context.enter(); + eventLoop = EventLoopInterop.obtainEventLoop(context); + } + + public void cleanup() { + Context context = Context.getCurrentContext(); + if (context == null) { + throw new IllegalStateException("No current context"); + } + EventLoopInterop.cleanupEventLoop(context); + Context.exit(); + } + + /** + * Run a Js script at a given path + * @param caller the resource of the script that invokes the Js code + * @param path the path to the JS script + * @param globalBindings the global bindings for the script + * @param arguments the arguments from the use-plugin + * @param callback callback that will receive the result of the script + */ + public void run(Resource caller, String path, Bindings globalBindings, Bindings arguments, UnaryCallback callback) { + Resource scriptResource = caller.getChild(path); + SlingScriptHelper scriptHelper = (SlingScriptHelper) globalBindings.get(SlingBindings.SLING); + Resource componentCaller = ResourceResolution.resolveComponentForRequest(caller.getResourceResolver(), scriptHelper.getRequest()); + if (scriptResource == null) { + scriptResource = ResourceResolution.resolveComponentRelative(caller.getResourceResolver(), componentCaller, path); + } + if (scriptResource == null) { + scriptResource = ResourceResolution.resolveComponentRelative(caller.getResourceResolver(), caller, path); + } + if (scriptResource == null) { + throw new SightlyUseException("Required script resource could not be located: " + path); + } + runResource(scriptResource, globalBindings, arguments, callback); + } + + public void runResource(Resource scriptResource, Bindings globalBindings, Bindings arguments, UnaryCallback callback) { + ScriptContext scriptContext = new SimpleScriptContext(); + CommonJsModule module = new CommonJsModule(); + Bindings scriptBindings = buildBindings(scriptResource, globalBindings, arguments, module); + scriptContext.setBindings(scriptBindings, ScriptContext.ENGINE_SCOPE); + runScript(scriptResource, scriptContext, callback, module); + } + + public AsyncContainer runResource(Resource scriptResource, Bindings globalBindings, Bindings arguments) { + AsyncContainer asyncContainer = new AsyncContainer(); + runResource(scriptResource, globalBindings, arguments, asyncContainer.createCompletionCallback()); + return asyncContainer; + } + + /** + * Run a script at a given path + * @param caller the resource of the script that invokes the Js code + * @param path the path to the JS script + * @param globalBindings bindings for the JS script + * @return an asynchronous container for the result + * @throws UnsupportedOperationException if this method is run when the event loop is not empty + */ + public AsyncContainer run(Resource caller, String path, Bindings globalBindings, Bindings arguments) { + AsyncContainer asyncContainer = new AsyncContainer(); + run(caller, path, globalBindings, arguments, asyncContainer.createCompletionCallback()); + return asyncContainer; + } + + private Bindings buildBindings(Resource scriptResource, Bindings local, Bindings arguments, CommonJsModule commonJsModule) { + Bindings bindings = new SimpleBindings(); + bindings.putAll(engineBindings); + DependencyResolver dependencyResolver = new DependencyResolver(scriptResource, this, local); + UseFunction useFunction = new UseFunction(dependencyResolver, arguments); + bindings.put(Variables.JS_USE, useFunction); + bindings.put(Variables.MODULE, commonJsModule); + bindings.put(Variables.EXPORTS, commonJsModule.getExports()); + bindings.put(Variables.CONSOLE, new Console(LoggerFactory.getLogger(scriptResource.getName()))); + bindings.putAll(local); + return bindings; + } + + private void runScript(Resource scriptResource, ScriptContext scriptContext, UnaryCallback callback, CommonJsModule commonJsModule) { + eventLoop.schedule(scriptTask(scriptResource, scriptContext, callback, commonJsModule)); + } + + private Task scriptTask(final Resource scriptResource, final ScriptContext scriptContext, + final UnaryCallback callback, final CommonJsModule commonJsModule) { + return new Task(new Runnable() { + @Override + public void run() { + Reader reader = null; + try { + reader = new InputStreamReader(scriptResource.adaptTo(InputStream.class)); + Object result = jsEngine.eval(reader, scriptContext); + if (commonJsModule.isModified()) { + result = commonJsModule.getExports(); + } + if (result instanceof AsyncContainer) { + ((AsyncContainer) result).addListener(callback); + } else { + callback.invoke(result); + } + } catch (ScriptException e) { + throw new SightlyUseException(e); + } finally { + IOUtils.closeQuietly(reader); + } + } + }); + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsEnvironment.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.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.js.impl; + +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +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.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.SlingScriptHelper; +import org.apache.sling.scripting.sightly.js.impl.async.AsyncContainer; +import org.apache.sling.scripting.sightly.js.impl.async.AsyncExtractor; +import org.apache.sling.scripting.sightly.js.impl.rhino.JsValueAdapter; +import org.apache.sling.scripting.sightly.render.RenderContext; +import org.apache.sling.scripting.sightly.use.ProviderOutcome; +import org.apache.sling.scripting.sightly.use.UseProvider; +import org.osgi.framework.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use provider for JS scripts. Ensures proper integration between Sightly & JS code-behind. + */ +@Component( + metatype = true, + label = "Apache Sling Scripting Sightly JavaScript Use Provider", + description = "The JavaScript Use Provider is responsible for instantiating JavaScript Use-API objects." +) +@Service(UseProvider.class) +@Properties({ + @Property( + name = Constants.SERVICE_RANKING, + label = "Service Ranking", + description = "The Service Ranking value acts as the priority with which this Use Provider is queried to return an " + + "Use-object. A higher value represents a higher priority.", + intValue = 90, + propertyPrivate = false + ) +}) +public class JsUseProvider implements UseProvider { + + private static final String JS_ENGINE_NAME = "javascript"; + + private static final Logger log = LoggerFactory.getLogger(JsUseProvider.class); + private static final JsValueAdapter jsValueAdapter = new JsValueAdapter(new AsyncExtractor()); + + @Reference + private ScriptEngineManager scriptEngineManager = null; + + @Reference + private ResourceResolverFactory rrf = null; + + @Override + public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) { + Bindings globalBindings = renderContext.getBindings(); + if (!Utils.isJsScript(identifier)) { + return ProviderOutcome.failure(); + } + ScriptEngine jsEngine = obtainEngine(); + if (jsEngine == null) { + log.warn("No JavaScript engine defined"); + return ProviderOutcome.failure(); + } + SlingScriptHelper scriptHelper = Utils.getHelper(globalBindings); + JsEnvironment environment = null; + ResourceResolver adminResolver = null; + try { + environment = new JsEnvironment(jsEngine); + environment.initialize(); + String callerPath = scriptHelper.getScript().getScriptResource().getPath(); + boolean allowedExecutablePath = false; + adminResolver = rrf.getAdministrativeResourceResolver(null); + for (String path : adminResolver.getSearchPath()) { + if (callerPath.startsWith(path)) { + allowedExecutablePath = true; + break; + } + } + if (allowedExecutablePath) { + Resource caller = adminResolver.getResource(callerPath); + AsyncContainer asyncContainer = environment.run(caller, identifier, globalBindings, arguments); + return ProviderOutcome.success(jsValueAdapter.adapt(asyncContainer)); + } + return ProviderOutcome.failure(); + } catch (LoginException e) { + log.error("Unable to load JS script " + identifier, e); + } finally { + if (environment != null) { + environment.cleanup(); + } + if (adminResolver != null) { + adminResolver.close(); + } + } + return ProviderOutcome.failure(); + } + + private ScriptEngine obtainEngine() { + return scriptEngineManager.getEngineByName(JS_ENGINE_NAME); + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Utils.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Utils.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Utils.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Utils.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.js.impl; + +import javax.script.Bindings; +import javax.script.SimpleBindings; +import java.util.Collections; + +import org.apache.commons.lang.StringUtils; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; + +/** + * Utilities for script evaluation + */ +public class Utils { + private static final String EXTENSION = "js"; + + public static final Bindings EMPTY_BINDINGS = new SimpleBindings(Collections.<String, Object>emptyMap()); + + public static SlingScriptHelper getHelper(Bindings bindings) { + return (SlingScriptHelper) bindings.get(SlingBindings.SLING); + } + + public static boolean isJsScript(String identifier) { + String extension = StringUtils.substringAfterLast(identifier, "."); + return EXTENSION.equalsIgnoreCase(extension); + } + +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Utils.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Variables.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Variables.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Variables.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Variables.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.js.impl; + +/** + * Variables exposed to js scripts + */ +public final class Variables { + + public static final String CONSOLE = "console"; + + public static final String JS_USE = "use"; + public static final String SET_TIMEOUT = "setTimeout"; + public static final String SET_IMMEDIATE = "setImmediate"; + + public static final String MODULE = "module"; + public static final String EXPORTS = "exports"; +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/Variables.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncContainer.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncContainer.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncContainer.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncContainer.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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.js.impl.async; + +import java.util.ArrayList; +import java.util.List; + +/** + * Simple container for asynchronously provided values + */ +public class AsyncContainer { + + private Object value; + private boolean completed; + private List<UnaryCallback> callbacks = new ArrayList<UnaryCallback>(); + + /** + * Add a listener that will receive the value in this container when it will + * be filled. If the container already has a value, the callback is called + * immediately. + * @param unaryCallback the callback that will receive the result + */ + public void addListener(UnaryCallback unaryCallback) { + callbacks.add(unaryCallback); + if (completed) { + notifyListener(unaryCallback); + } + } + + /** + * Get the result of this holder + * @return the holder result + * @throws java.util.NoSuchElementException if the result has not yet been set + */ + public Object getResult() { + return value; + } + + /** + * Check whether the container was completed with a value + * @return the completion status + */ + public boolean isCompleted() { + return completed; + } + + /** + * Complete this async container with a value + * @param value the result value + * @throws java.lang.IllegalStateException if the container has been previously filled + */ + public void complete(Object value) { + if (completed) { + throw new IllegalStateException("Value was already completed"); + } + completed = true; + this.value = value; + for (UnaryCallback callback : callbacks) { + notifyListener(callback); + } + } + + /** + * Create a callback that will complete this container + * @return the completion callback + */ + public UnaryCallback createCompletionCallback() { + return new UnaryCallback() { + @Override + public void invoke(Object arg) { + complete(arg); + } + }; + } + + private void notifyListener(UnaryCallback unaryCallback) { + unaryCallback.invoke(value); + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncContainer.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncExtractor.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncExtractor.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncExtractor.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncExtractor.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.js.impl.async; + +import org.mozilla.javascript.BaseFunction; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.apache.sling.scripting.sightly.js.impl.loop.EventLoopInterop; +import org.apache.sling.scripting.sightly.use.SightlyUseException; + +/** + * + */ +public class AsyncExtractor { + + public static final String THEN_METHOD = "then"; + + public void extract(Object jsObj, UnaryCallback unaryCallback) { + if (!isPromise(jsObj)) { + unaryCallback.invoke(jsObj); + } + if (jsObj instanceof AsyncContainer) { + ((AsyncContainer) jsObj).addListener(unaryCallback); + } + if (jsObj instanceof ScriptableObject) { + ScriptableObject scriptableObject = (ScriptableObject) jsObj; + decodeJSPromise(scriptableObject, unaryCallback); + } + } + + private void decodeJSPromise(final Scriptable promise, final UnaryCallback callback) { + try { + Context context = Context.enter(); + final AsyncContainer errorContainer = new AsyncContainer(); + final Function errorHandler = createErrorHandler(errorContainer); + final Function successHandler = convertCallback(callback); + EventLoopInterop.schedule(context, new Runnable() { + @Override + public void run() { + ScriptableObject.callMethod(promise, THEN_METHOD, + new Object[] {successHandler, errorHandler}); + } + }); + if (errorContainer.isCompleted()) { + throw new SightlyUseException("Promise has completed with failure: " + + Context.toString(errorContainer.getResult())); + } + } finally { + Context.exit(); + } + } + + private Function createErrorHandler(AsyncContainer asyncContainer) { + return convertCallback(asyncContainer.createCompletionCallback()); + } + + public boolean isPromise(Object jsObj) { + if (jsObj instanceof AsyncContainer) { + return true; + } + if (jsObj instanceof ScriptableObject) { + Scriptable scriptable = (Scriptable) jsObj; + return ScriptableObject.hasProperty(scriptable, THEN_METHOD); + } + return false; + } + + private static Function convertCallback(final UnaryCallback unaryCallback) { + return new BaseFunction() { + @Override + public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { + Object arg = (args.length == 0) ? Context.getUndefinedValue() : args[0]; + unaryCallback.invoke(arg); + return Context.getUndefinedValue(); + } + }; + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/AsyncExtractor.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingBindingsValuesProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingBindingsValuesProvider.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingBindingsValuesProvider.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingBindingsValuesProvider.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.js.impl.async; + +import javax.script.Bindings; + +import org.apache.sling.scripting.api.BindingsValuesProvider; +import org.apache.sling.scripting.sightly.js.impl.Variables; + +/** + * Value provider for timing functions + */ +public final class TimingBindingsValuesProvider implements BindingsValuesProvider { + + public static final TimingBindingsValuesProvider INSTANCE = new TimingBindingsValuesProvider(); + + private TimingBindingsValuesProvider() { + } + + @Override + public void addBindings(Bindings bindings) { + bindings.put(Variables.SET_TIMEOUT, TimingFunction.INSTANCE); + bindings.put(Variables.SET_IMMEDIATE, TimingFunction.INSTANCE); + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingBindingsValuesProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingFunction.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingFunction.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingFunction.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingFunction.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.js.impl.async; + +import org.mozilla.javascript.BaseFunction; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.apache.sling.scripting.sightly.js.impl.loop.EventLoopInterop; +import org.apache.sling.scripting.sightly.js.impl.rhino.JsUtils; + +/** + * Timing function for JS scripts that use async constructs + */ +public final class TimingFunction extends BaseFunction { + + public static final TimingFunction INSTANCE = new TimingFunction(); + + private TimingFunction() { + } + + @Override + public Object call(final Context cx, final Scriptable scope, Scriptable thisObj, Object[] args) { + if (args.length == 0) { + return Context.getUndefinedValue(); + } + if (!(args[0] instanceof Function)) { + throw new IllegalArgumentException("Timing function must receive a function as the first argument"); + } + final Function function = (Function) args[0]; + return EventLoopInterop.schedule(cx, new Runnable() { + @Override + public void run() { + JsUtils.callFn(function, cx, scope, null, new Object[0]); + } + }); + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/TimingFunction.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/UnaryCallback.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/UnaryCallback.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/UnaryCallback.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/UnaryCallback.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.js.impl.async; + +/** + * Unary callback function + */ +public interface UnaryCallback { + + /** + * Call the callback with one argument + * @param arg the callback argument + */ + void invoke(Object arg); +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/async/UnaryCallback.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/CommonJsModule.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/CommonJsModule.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/CommonJsModule.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/CommonJsModule.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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.js.impl.cjs; + +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; + +/** + * CommonJS module implementation + */ +public class CommonJsModule extends ScriptableObject { + + private static final String EXPORTS = "exports"; + + private Object exports = new ExportsObject(); + private boolean modifiedModule; + + + @Override + public Object get(String name, Scriptable start) { + if (name.equals(EXPORTS)) { + return exports; + } + return super.get(name, start); + } + + @Override + public void put(String name, Scriptable start, Object value) { + if (name.equals(EXPORTS)) { + setExports(value); + } else { + super.put(name, start, value); + } + } + + public Object getExports() { + return exports; + } + + public void setExports(Object exports) { + modifiedModule = true; + this.exports = exports; + } + + public boolean isModified() { + return modifiedModule || ((ExportsObject) exports).isModified(); + } + + @Override + public String getClassName() { + return "Module"; + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/CommonJsModule.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/ExportsObject.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/ExportsObject.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/ExportsObject.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/ExportsObject.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.js.impl.cjs; + + +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; + +/** + * The default exports object + */ +public class ExportsObject extends ScriptableObject { + + private boolean modified; + + @Override + public void put(String name, Scriptable start, Object value) { + modified = true; + super.put(name, start, value); + } + + public boolean isModified() { + return modified; + } + + @Override + public String getClassName() { + return "exports"; + } +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/cjs/ExportsObject.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/jsapi/SlyBindingsValuesProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/jsapi/SlyBindingsValuesProvider.java?rev=1642281&view=auto ============================================================================== --- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/jsapi/SlyBindingsValuesProvider.java (added) +++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/jsapi/SlyBindingsValuesProvider.java Fri Nov 28 10:18:01 2014 @@ -0,0 +1,315 @@ +/******************************************************************************* + * 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.js.impl.jsapi; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; + +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.SimpleBindings; +import javax.servlet.http.HttpServletRequest; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.PropertyUnbounded; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; +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.commons.osgi.PropertiesUtil; +import org.apache.sling.scripting.api.BindingsValuesProvider; +import org.apache.sling.scripting.sightly.js.impl.JsEnvironment; +import org.apache.sling.scripting.sightly.js.impl.Variables; +import org.apache.sling.scripting.sightly.js.impl.async.AsyncContainer; +import org.apache.sling.scripting.sightly.js.impl.async.AsyncExtractor; +import org.apache.sling.scripting.sightly.js.impl.async.TimingBindingsValuesProvider; +import org.apache.sling.scripting.sightly.js.impl.async.TimingFunction; +import org.apache.sling.scripting.sightly.js.impl.cjs.CommonJsModule; +import org.apache.sling.scripting.sightly.js.impl.rhino.HybridObject; +import org.apache.sling.scripting.sightly.js.impl.rhino.JsValueAdapter; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Script; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides the {@code sly} and {@code aem} namespaces for usage in Sightly & JS scripts + * called from Sightly + */ +@Component(metatype = true, label = "Apache Sling Scripting Sightly JavaScript Bindings Provider", + description = "The Apache Sling Scripting Sightly JavaScript Bindings Provider loads the JS Use-API and makes it available in the" + + " bindings map.") +@Service(BindingsValuesProvider.class) +@Properties({ + @Property(name = "javax.script.name", value = "sightly", propertyPrivate = true), + @Property(name = "service.ranking", intValue = 100), + @Property( + name = SlyBindingsValuesProvider.SCR_PROP_JS_BINDING_IMPLEMENTATIONS, + value = { + "sightly:" + SlyBindingsValuesProvider.SLING_NS_PATH + }, + unbounded = PropertyUnbounded.ARRAY, + label = "Script Factories", + description = "Script factories to load in the bindings map. The entries should be in the form " + + "'namespace:/path/from/repository'." + ) +}) +@SuppressWarnings("unused") +public class SlyBindingsValuesProvider implements BindingsValuesProvider { + + public static final String SCR_PROP_JS_BINDING_IMPLEMENTATIONS = "org.apache.sling.scripting.sightly.js.bindings"; + + public static final String SLING_NS_PATH = "/libs/sling/sightly/js/internal/sly.js"; + public static final String Q_PATH = "/libs/sling/sightly/js/3rd-party/q.js"; + + private static final String REQ_NS = SlyBindingsValuesProvider.class.getCanonicalName(); + + private static final Logger log = LoggerFactory.getLogger(SlyBindingsValuesProvider.class); + + @Reference + private ScriptEngineManager scriptEngineManager; + + @Reference + private ResourceResolverFactory rrf = null; + + private final AsyncExtractor asyncExtractor = new AsyncExtractor(); + private final JsValueAdapter jsValueAdapter = new JsValueAdapter(asyncExtractor); + + private Map<String, String> scriptPaths = new HashMap<String, String>(); + private Map<String, Function> factories = new HashMap<String, Function>(); + + private Script qScript; + private final ScriptableObject qScope = createQScope(); + + @Override + public void addBindings(Bindings bindings) { + if (needsInit()) { + init(bindings); + } + Context context = null; + try { + context = Context.enter(); + Object qInstance = obtainQInstance(context, bindings); + if (qInstance == null) { + return; + } + for (Map.Entry<String, Function> entry : factories.entrySet()) { + addBinding(context, entry.getValue(), bindings, entry.getKey(), qInstance); + } + } finally { + if (context != null) { + Context.exit(); + } + } + } + + @Activate + protected void activate(ComponentContext componentContext) { + Dictionary properties = componentContext.getProperties(); + String[] factories = PropertiesUtil.toStringArray(properties.get(SCR_PROP_JS_BINDING_IMPLEMENTATIONS), new String[]{SLING_NS_PATH}); + scriptPaths = new HashMap<String, String>(factories.length); + for (String f : factories) { + String[] parts = f.split(":"); + if (parts.length == 2) { + scriptPaths.put(parts[0], parts[1]); + } + } + } + + @Deactivate + protected void deactivate(ComponentContext componentContext) { + if (scriptPaths != null) { + scriptPaths.clear(); + } + if (factories != null) { + factories.clear(); + } + } + + + private void addBinding(Context context, Function factory, Bindings bindings, String globalName, Object qInstance) { + if (factory == null) { + return; + } + Object result = factory.call(context, factory, factory, new Object[] {bindings, qInstance}); + HybridObject global = new HybridObject((Scriptable) result, jsValueAdapter); + bindings.put(globalName, global); + } + + private boolean needsInit() { + return factories == null || factories.isEmpty() || qScript == null; + } + + private synchronized void init(Bindings bindings) { + if (needsInit()) { + ensureFactoriesLoaded(bindings); + } + } + + private void ensureFactoriesLoaded(Bindings bindings) { + JsEnvironment jsEnvironment = null; + try { + ScriptEngine scriptEngine = obtainEngine(); + if (scriptEngine == null) { + return; + } + jsEnvironment = new JsEnvironment(scriptEngine); + jsEnvironment.initialize(); + factories = new HashMap<String, Function>(scriptPaths.size()); + for (Map.Entry<String, String> entry : scriptPaths.entrySet()) { + factories.put(entry.getKey(), loadFactory(jsEnvironment, entry.getValue(), bindings)); + } + qScript = loadQScript(); + } finally { + if (jsEnvironment != null) { + jsEnvironment.cleanup(); + } + } + } + + private Function loadFactory(JsEnvironment jsEnvironment, String path, Bindings bindings) { + ResourceResolver resolver = null; + try { + resolver = rrf.getAdministrativeResourceResolver(null); + Resource resource = resolver.getResource(path); + if (resource == null) { + log.warn("Sly namespace loader could not find the following script: " + path); + return null; + } + AsyncContainer container = jsEnvironment.runResource(resource, createBindings(bindings), new SimpleBindings()); + Object obj = container.getResult(); + if (!(obj instanceof Function)) { + log.warn("Script was expected to return a function"); + return null; + } + return (Function) obj; + } catch (LoginException e) { + log.error("Cannot evaluate script " + path, e); + return null; + } finally { + if (resolver != null) { + resolver.close(); + } + } + } + + private Bindings createBindings(Bindings global) { + Bindings bindings = new SimpleBindings(); + bindings.putAll(global); + TimingBindingsValuesProvider.INSTANCE.addBindings(bindings); + return bindings; + } + + private ScriptEngine obtainEngine() { + return scriptEngineManager.getEngineByName("javascript"); + } + + private Object obtainQInstance(Context context, Bindings bindings) { + if (qScript == null) { + return null; + } + HttpServletRequest request = (HttpServletRequest) bindings.get(SlingBindings.REQUEST); + Object qInstance = null; + if (request != null) { + qInstance = request.getAttribute(REQ_NS); + } + if (qInstance == null) { + qInstance = createQInstance(context, qScript); + if (request != null) { + request.setAttribute(REQ_NS, qInstance); + } + } + return qInstance; + } + + private ScriptableObject createQScope() { + Context context = Context.enter(); + try { + ScriptableObject scope = context.initStandardObjects(); + ScriptableObject.putProperty(scope, Variables.SET_IMMEDIATE, TimingFunction.INSTANCE); + ScriptableObject.putProperty(scope, Variables.SET_TIMEOUT, TimingFunction.INSTANCE); + return scope; + } finally { + Context.exit(); + } + } + + private Object createQInstance(Context context, Script qScript) { + CommonJsModule module = new CommonJsModule(); + Scriptable tempScope = context.newObject(qScope); + ScriptableObject.putProperty(tempScope, Variables.MODULE, module); + ScriptableObject.putProperty(tempScope, Variables.EXPORTS, module.getExports()); + qScript.exec(context, tempScope); + return module.getExports(); + } + + private Script loadQScript() { + ResourceResolver resourceResolver = null; + Context context = Context.enter(); + context.initStandardObjects(); + context.setOptimizationLevel(9); + InputStream reader = null; + try { + resourceResolver = rrf.getAdministrativeResourceResolver(null); + Resource resource = resourceResolver.getResource(Q_PATH); + if (resource == null) { + log.warn("Could not load Q library at path: " + Q_PATH); + return null; + } + reader = resource.adaptTo(InputStream.class); + if (reader == null) { + log.warn("Could not read content of Q library"); + return null; + } + return context.compileReader(new InputStreamReader(reader), Q_PATH, 0, null); + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + Context.exit(); + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + log.error("Error while closing reader", e); + } + } + if (resourceResolver != null) { + resourceResolver.close(); + } + } + } + +} Propchange: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/jsapi/SlyBindingsValuesProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain