You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2014/11/14 15:05:03 UTC
svn commit: r1639641 [2/15] - in /sling/trunk/contrib/scripting/sightly: ./
engine/ engine/src/ engine/src/main/ engine/src/main/antlr4/
engine/src/main/antlr4/org/ engine/src/main/antlr4/org/apache/
engine/src/main/antlr4/org/apache/sling/ engine/src/...
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ObjectModel.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ObjectModel.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ObjectModel.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ObjectModel.java Fri Nov 14 14:04:56 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.api;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Defines the dynamic queries that values must support
+ * in Sightly
+ */
+public interface ObjectModel {
+
+ String PROPERTY_ACCESS = "resolveProperty";
+ String COLLECTION_COERCE = "coerceToCollection";
+ String NUMERIC_COERCE = "coerceNumeric";
+ String STRING_COERCE = "coerceToString";
+ String BOOLEAN_COERCE = "coerceToBoolean";
+
+ String STRICT_EQ = "strictEq";
+ String LEQ = "leq";
+ String LT = "lt";
+
+ /**
+ * 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 coerceToString(Object target);
+
+ /**
+ * Convert the given object to a boolean value
+ * @param object - the target object
+ * @return - the boolean representation of that object
+ */
+ boolean coerceToBoolean(Object object);
+
+ /**
+ * Coerce the object to a numeric value
+ * @param object - the target object
+ * @return - the numeric representation
+ */
+ Number coerceNumeric(Object object);
+
+ /**
+ * Force the conversion of the object to a collection
+ * @param object - the target object
+ * @return the collection representation of the object
+ */
+ Collection<Object> coerceToCollection(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 coerceToMap(Object object);
+
+ /**
+ * Check whether the left argument equals the right one
+ * @param left the left argument
+ * @param right the right argument
+ * @return true if arguments are equal
+ */
+ boolean strictEq(Object left, Object right);
+
+ /**
+ * Check if left < right
+ * @param left the left argument
+ * @param right the right argument
+ * @return true if left < right
+ */
+ boolean lt(Object left, Object right);
+
+ /**
+ * Check if left < right
+ * @param left the left argument
+ * @param right the right argument
+ * @return true if left < right
+ */
+ boolean leq(Object left, Object right);
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ProviderOutcome.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ProviderOutcome.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ProviderOutcome.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ProviderOutcome.java Fri Nov 14 14:04:56 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.api;
+
+/**
+ * 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;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Record.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Record.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Record.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Record.java Fri Nov 14 14:04:56 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.api;
+
+import java.util.Set;
+
+/**
+ * A key-value immutable object understood by the Sightly runtime
+ * @param <T> the type of values for this record
+ */
+public interface Record<T> {
+
+ /**
+ * Get the value of the specified property
+ * @param name the name of the property
+ * @return the value of the property or null if this record does not
+ * have the specified property
+ */
+ T get(String name);
+
+ /**
+ * Get the set of properties for this record
+ * @return this record's properties
+ */
+ Set<String> properties();
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderContext.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderContext.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderContext.java Fri Nov 14 14:04:56 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.api;
+
+import java.util.Map;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+
+/**
+ * Rendering context for Sightly rendering units.
+ * @see RenderUnit
+ */
+public class RenderContext {
+
+ private final StackedWriter writer;
+ private final Bindings bindings;
+ private final ObjectModel objectModel;
+ private final SightlyRuntime runtime;
+ private final UnitLocator unitLocator;
+
+ public RenderContext(StackedWriter writer, Bindings bindings, ObjectModel objectModel, SightlyRuntime runtime, UnitLocator unitLocator) {
+ this.writer = writer;
+ this.bindings = bindings;
+ this.objectModel = objectModel;
+ this.runtime = runtime;
+ this.unitLocator = unitLocator;
+ }
+
+ /**
+ * Get the writer where the content should be written
+ * @return - a stacked writer
+ */
+ public StackedWriter getWriter() {
+ return writer;
+ }
+
+ /**
+ * Provide the bindings for this script
+ * @return - the list of global bindings available to the script
+ */
+ public Bindings getBindings() {
+ return bindings;
+ }
+
+ /**
+ * Get an instance of the objectModel object model
+ * @return - a objectModel object model instance
+ */
+ public ObjectModel getObjectModel() {
+ return objectModel;
+ }
+
+ /**
+ * Get the available Sightly runtime
+ * @return - an instance of the Sightly runtime
+ */
+ public SightlyRuntime getRuntime() {
+ return runtime;
+ }
+
+ /**
+ * Get the unit locator
+ * @return - a unit locator
+ */
+ public UnitLocator getUnitLocator() {
+ return unitLocator;
+ }
+
+ /**
+ * Create a new render context with different bindings
+ * @param newBindings - the new set of bindings
+ * @return - the new render context
+ */
+ public RenderContext withBindings(Bindings newBindings) {
+ return new RenderContext(this.writer, newBindings, this.objectModel, this.runtime, this.unitLocator);
+ }
+
+ /**
+ * Create a new render context with additional bindings
+ * @param additionalBindings - a dictionary of variables
+ * @return - the new render context
+ */
+ public RenderContext withAddedBindings(Map additionalBindings) {
+ Bindings newBindings = new SimpleBindings();
+ newBindings.putAll(this.bindings);
+ //noinspection unchecked
+ newBindings.putAll(additionalBindings);
+ return withBindings(newBindings);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderUnit.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderUnit.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderUnit.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RenderUnit.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.api;
+
+import javax.script.Bindings;
+
+/**
+ * Basic unit of rendering. This also extends the record interface.
+ * The properties for a unit are the sub-units
+ */
+public interface RenderUnit extends Record<RenderUnit> {
+
+ /**
+ * Render the main script template
+ * @param renderContext - the rendering context
+ * @param arguments - the arguments for this unit
+ */
+ void render(RenderContext renderContext, Bindings arguments);
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ResourceResolution.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ResourceResolution.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ResourceResolution.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/ResourceResolution.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.api;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.jcr.resource.JcrResourceConstants;
+
+/**
+ * Utility class which used by the Sightly engine & extensions
+ * to resolve resources
+ */
+public class ResourceResolution {
+
+ /**
+ * Maximum number of iterations that can be performed when searching for a resource in
+ * the resource superType chain
+ */
+ private static final int RECURSION_LIMIT = 100;
+
+ /**
+ * Resolve the resource with the given path relative to the base resource, using the
+ * resource super type logic
+ * @param resourceResolver The resource resolver to be used
+ * @param base the base resource. It can be null if path is absolute
+ * @param path the path to the resource
+ * @return the retrieved resource or null if no resource was found
+ * @throws java.lang.UnsupportedOperationException if the resource is not in the resource resolver's search path
+ * @throws java.lang.IllegalStateException if the number of steps necessary to search for the resource on the resource
+ * superType chain has reached the maximum limit
+ * @throws java.lang.IllegalArgumentException if a null componentResource is provided but the path is not absolute
+ */
+ public static Resource resolveComponentRelative(ResourceResolver resourceResolver, Resource base, String path) {
+ Resource componentResource = null;
+ if (base != null) {
+ if ("nt:file".equals(base.getResourceType())) {
+ componentResource = retrieveParent(resourceResolver, base);
+ } else {
+ componentResource = base;
+ }
+ }
+ return resolveComponent(resourceResolver, componentResource, path);
+ }
+
+ public static Resource resolveComponentForRequest(ResourceResolver resolver, SlingHttpServletRequest request) {
+ String resourceType = request.getResource().getResourceType();
+ if (StringUtils.isNotEmpty(resourceType)) {
+ if (resourceType.startsWith("/")) {
+ return resolver.getResource(resourceType);
+ }
+ for (String searchPath : resolver.getSearchPath()) {
+ String componentPath = ResourceUtil.normalize(searchPath + "/" + resourceType);
+ Resource componentResource = resolver.getResource(componentPath);
+ if (componentResource != null) {
+ return componentResource;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resolve the resource in the specified component
+ * @param resourceResolver The resource resolver to be used
+ * @param componentResource The resource for the component. It can be null if path is absolute
+ * @param path the path to the resource
+ * @return the retrieved resource or null if no resource was found
+ * @throws java.lang.UnsupportedOperationException if the resource is not in the resource resolver's search path
+ * @throws java.lang.IllegalStateException if more than {@link ResourceResolution#RECURSION_LIMIT} steps were
+ * necessary to search for the resource on the resource superType chain
+ * @throws java.lang.IllegalArgumentException if a null componentResource is provided but the path is not absolute
+ */
+ private static Resource resolveComponent(ResourceResolver resourceResolver, Resource componentResource, String path) {
+ if (resourceResolver == null || path == null) {
+ throw new NullPointerException("Arguments cannot be null");
+ }
+ Resource resource = null;
+ if (isAbsolutePath(path)) {
+ resource = resourceResolver.getResource(path);
+ }
+ if (resource == null) {
+ if (componentResource == null) {
+ throw new IllegalArgumentException("Argument cannot be null if path is not absolute: " + path);
+ }
+ resource = recursiveResolution(resourceResolver, componentResource, path);
+ }
+ if (resource == null) {
+ resource = locateInSearchPath(resourceResolver, path);
+ }
+ return resource != null ? searchPathChecked(resourceResolver, resource) : null;
+ }
+
+ private static Resource recursiveResolution(ResourceResolver resourceResolver, Resource componentResource, String path) {
+ for (int iteration = 0; iteration < RECURSION_LIMIT; iteration++) {
+ Resource resource = resourceResolver.getResource(componentResource, path);
+ if (resource != null) {
+ return resource;
+ }
+ componentResource = findSuperComponent(resourceResolver, componentResource);
+ if (componentResource == null) {
+ return null;
+ }
+ }
+ //at this point we have reached recursion limit
+ throw new IllegalStateException("Searching for resource in component chain took more than " +
+ RECURSION_LIMIT + " steps");
+ }
+
+ private static Resource locateInSearchPath(ResourceResolver resourceResolver, String path) {
+ for (String searchPath : resourceResolver.getSearchPath()) {
+ String fullPath = searchPath + path;
+ Resource resource = resourceResolver.getResource(fullPath);
+ if (resource != null && resource.getPath().startsWith(searchPath)) { //prevent path traversal attack
+ return resource;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isInSearchPath(ResourceResolver resourceResolver, Resource resource) {
+ String resourcePath = resource.getPath();
+ for (String path : resourceResolver.getSearchPath()) {
+ if (resourcePath.startsWith(path)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Resource findSuperComponent(ResourceResolver resourceResolver, Resource base) {
+ String superType = resourceResolver.getParentResourceType(base);
+ if (superType == null) {
+ return null;
+ }
+ return resourceResolver.getResource(superType);
+ }
+
+ private static Resource searchPathChecked(ResourceResolver resourceResolver, Resource resource) {
+ if (!isInSearchPath(resourceResolver, resource)) {
+ throw new UnsupportedOperationException("Access to resource " + resource.getPath() + " is denied, since the resource does not reside on the search path");
+ }
+ return resource;
+ }
+
+ private static Resource retrieveParent(ResourceResolver resourceResolver, Resource resource) {
+ String parentPath = ResourceUtil.getParent(resource.getPath());
+ if (parentPath == null) {
+ return null;
+ }
+ return resourceResolver.getResource(parentPath);
+ }
+
+ private static boolean isAbsolutePath(String path) {
+ return path.startsWith("/");
+ }
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtension.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtension.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtension.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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.api;
+
+/**
+ * Extensions provided to the Sightly runtime
+ */
+public interface RuntimeExtension {
+
+ /**
+ * Provide an instance of this extension
+ * @param renderContext - the runtime context
+ * @return an extension instance
+ */
+ ExtensionInstance provide(RenderContext renderContext);
+
+ /**
+ * The name of this extension
+ * @return - the name of the extension
+ */
+ String name();
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionComponent.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionComponent.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionComponent.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionComponent.java Fri Nov 14 14:04:56 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.api;
+
+import java.util.Dictionary;
+
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * Component-based implementation for extensions
+ */
+public abstract class RuntimeExtensionComponent implements RuntimeExtension {
+
+ public static final String SCR_PROP_NAME = "org.apache.sling.scripting.sightly.rtextension.name";
+
+ private String name;
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ protected void activate(ComponentContext componentContext) {
+ Dictionary properties = componentContext.getProperties();
+ name = (String) properties.get(SCR_PROP_NAME);
+ }
+
+ protected void checkArgumentCount(Object[] arguments, int count) {
+ if (arguments.length != count) {
+ throw new RuntimeExtensionException(String.format("Extension %s requires %d arguments", name(), count));
+ }
+ }
+
+ protected void checkArguments(Object[] arguments, Class<?> ... classes) {
+ checkArgumentCount(arguments, classes.length);
+ for (int i = 0; i < arguments.length; i++) {
+ Object arg = arguments[i];
+ Class<?> cls = classes[i];
+ if (!(cls.isAssignableFrom(arg.getClass()))) {
+ throw new RuntimeExtensionException(String.format("Argument on position %d is not of expected type %s",
+ i, cls.getCanonicalName()));
+ }
+ }
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionException.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/RuntimeExtensionException.java Fri Nov 14 14:04:56 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.api;
+
+/**
+ * Exception thrown by runtime extensions
+ * @see RuntimeExtension
+ */
+public class RuntimeExtensionException extends RuntimeException {
+
+ public RuntimeExtensionException() {
+ }
+
+ public RuntimeExtensionException(String message) {
+ super(message);
+ }
+
+ public RuntimeExtensionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public RuntimeExtensionException(Throwable cause) {
+ super(cause);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyEngineException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyEngineException.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyEngineException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyEngineException.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.api;
+
+/**
+ * Exceptions caused by the Sightly engine
+ */
+public class SightlyEngineException extends RuntimeException {
+
+ public SightlyEngineException() {
+ }
+
+ public SightlyEngineException(String message) {
+ super(message);
+ }
+
+ public SightlyEngineException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SightlyEngineException(Throwable cause) {
+ super(cause);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyParsingException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyParsingException.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyParsingException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyParsingException.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.api;
+
+/**
+ * The runtime {@code SightlyParsingException} is thrown during the parsing stage for any grammar offending input.
+ */
+public class SightlyParsingException extends RuntimeException {
+
+ private String offendingInput;
+
+ public SightlyParsingException() {
+ }
+
+ public SightlyParsingException(String message) {
+ super(message);
+ }
+
+ public SightlyParsingException(String message, String offendingInput) {
+ super(message);
+ this.offendingInput = offendingInput;
+ }
+
+ public SightlyParsingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SightlyParsingException(String message, String offendingInput, Throwable cause) {
+ super(message, cause);
+ this.offendingInput = offendingInput;
+ }
+
+ public SightlyParsingException(Throwable cause) {
+ super(cause);
+ }
+
+ public String getOffendingInput() {
+ return offendingInput;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRenderException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRenderException.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRenderException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRenderException.java Fri Nov 14 14:04:56 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.api;
+
+/**
+ * Exceptions generated by Sightly during runtime
+ */
+public class SightlyRenderException extends RuntimeException {
+
+ public SightlyRenderException() {
+ }
+
+ public SightlyRenderException(String message) {
+ super(message);
+ }
+
+ public SightlyRenderException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SightlyRenderException(Throwable cause) {
+ super(cause);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRuntime.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRuntime.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRuntime.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyRuntime.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.api;
+
+/**
+ * Runtime interface provided to Sightly scripts
+ */
+public interface SightlyRuntime {
+
+ /**
+ * Call the specified function name with the given arguments
+ * @param functionName - the name of the called function
+ * @param arguments - 0 or more arguments passed to the function
+ * @return - the object returned by the function
+ * @throws SightlyRenderException - if the function was
+ * not defined
+ */
+ Object call(String functionName, Object ... arguments);
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyUseException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyUseException.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyUseException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/SightlyUseException.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.api;
+
+/**
+ * Exception raised by the use resolving mechanism
+ */
+public class SightlyUseException extends RuntimeException {
+ public SightlyUseException() {
+ }
+
+ public SightlyUseException(String message) {
+ super(message);
+ }
+
+ public SightlyUseException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SightlyUseException(Throwable cause) {
+ super(cause);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/StackedWriter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/StackedWriter.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/StackedWriter.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/StackedWriter.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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.api;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Stack;
+
+/**
+ * Text writing utility which allows stacking of temporary buffers
+ */
+public class StackedWriter extends Writer {
+
+ private final PrintWriter baseWriter;
+ private final Stack<StringWriter> writerStack = new Stack<StringWriter>();
+ private PrintWriter current;
+
+ public StackedWriter(PrintWriter baseWriter) {
+ this.baseWriter = baseWriter;
+ this.current = baseWriter;
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ current.write(cbuf, off, len);
+ }
+
+ @Override
+ public void write(String text) {
+ current.write(text);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ current.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (writerStack.size() != 1) {
+ throw new UnsupportedOperationException("Stack is not empty");
+ }
+ current.close();
+ }
+
+ public void push() {
+ StringWriter writer = new StringWriter();
+ writerStack.push(writer);
+ current = new PrintWriter(writer);
+ }
+
+ public String pop() {
+ String output = null;
+ if (!writerStack.isEmpty()) {
+ StringWriter writer = writerStack.pop();
+ output = writer.toString();
+ }
+ if (writerStack.isEmpty()) {
+ current = baseWriter;
+ } else {
+ current = new PrintWriter(writerStack.peek());
+ }
+ return output;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UnitLocator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UnitLocator.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UnitLocator.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UnitLocator.java Fri Nov 14 14:04:56 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.api;
+
+/**
+ * Locates rendering units
+ */
+public interface UnitLocator {
+
+ /**
+ * Locate the given rendering unit
+ * @param path - the path of the unit
+ * @return - the rendering unit, or null if the path could not be resolved to a valid
+ * rendering unit
+ */
+ RenderUnit locate(String path);
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Use.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Use.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Use.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/Use.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.api;
+
+import javax.script.Bindings;
+
+public interface Use {
+
+ public void init(Bindings bindings);
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProvider.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProvider.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProvider.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.api;
+
+import javax.script.Bindings;
+
+/**
+ * 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
+ */
+public interface UseProvider extends Comparable<UseProvider> {
+
+ int DEFAULT_PRIORITY = 0;
+
+ /**
+ * 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);
+
+ /**
+ * The priority with which this use provider should be selected. Use 0 if you don't care
+ * @return the (possibly negative) priority of this provider
+ */
+ int priority();
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProviderComponent.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProviderComponent.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProviderComponent.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/api/UseProviderComponent.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * 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.api;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * Component-based use provider
+ */
+public abstract class UseProviderComponent implements UseProvider {
+
+ public static final String PRIORITY = "org.apache.sling.scripting.sightly.api.use.priority";
+
+ private int priority = DEFAULT_PRIORITY;
+
+ @Override
+ public int priority() {
+ return priority;
+ }
+
+ @Override
+ public int compareTo(UseProvider o) {
+ if (this.priority < o.priority()) {
+ return -1;
+ } else if (this.priority == o.priority()) {
+ return 0;
+ }
+ return 1;
+ }
+
+ @Activate
+ protected void activate(ComponentContext componentContext) {
+ priority = PropertiesUtil.toInteger(componentContext.getProperties().get(PRIORITY), DEFAULT_PRIORITY);
+ }
+
+ /**
+ * Combine to bindings objects. Priority goes to latter bindings
+ * @param former First map of bindings
+ * @param latter Second, with greater visibility, map of bindings
+ * @return the merging of the two maps
+ */
+ protected Bindings merge(Bindings former, Bindings latter) {
+ Bindings bindings = new SimpleBindings();
+ bindings.putAll(former);
+ bindings.putAll(latter);
+ return bindings;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/Dynamic.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/Dynamic.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/Dynamic.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/Dynamic.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * 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.common;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+
+/**
+ * Extends the object model by providing implementations for all Sightly
+ * operators.
+ */
+public class Dynamic implements ObjectModel {
+
+ private final ObjectModel model;
+
+ public Dynamic(ObjectModel model) {
+ this.model = model;
+ }
+
+ @Override
+ public Object resolveProperty(Object target, Object property) {
+ return model.resolveProperty(target, property);
+ }
+
+ @Override
+ public String coerceToString(Object target) {
+ return model.coerceToString(target);
+ }
+
+ @Override
+ public boolean coerceToBoolean(Object object) {
+ return model.coerceToBoolean(object);
+ }
+
+ @Override
+ public Collection<Object> coerceToCollection(Object object) {
+ return model.coerceToCollection(object);
+ }
+
+ @Override
+ public Number coerceNumeric(Object object) {
+ if (object instanceof Number) {
+ return (Number) object;
+ }
+ return 0;
+ }
+
+ @Override
+ public Map coerceToMap(Object object) {
+ return model.coerceToMap(object);
+ }
+
+ @Override
+ public boolean strictEq(Object left, Object right) {
+ return model.strictEq(left, right);
+ }
+
+ public boolean eq(Object left, Object right) {
+ if (left == null) {
+ return right == null;
+ }
+ return left.equals(right);
+ }
+
+ @Override
+ public boolean lt(Object left, Object right) {
+ return model.lt(left, right);
+ }
+
+ @Override
+ public boolean leq(Object left, Object right) {
+ return model.leq(left, right);
+ }
+
+ public Object and(Object left, Object right) {
+ if (coerceToBoolean(left)) {
+ return right;
+ }
+ return left;
+ }
+
+
+ public Object or(Object left, Object right) {
+ if (coerceToBoolean(left)) {
+ return left;
+ }
+ return right;
+ }
+
+
+ public Object not(Object obj) {
+ return !coerceToBoolean(obj);
+ }
+
+
+ public Object concatenate(Object left, Object right) {
+ return coerceToString(left) + coerceToString(right);
+ }
+
+
+ public Object isWhiteSpace(Object object) {
+ return StringUtils.isWhitespace(coerceToString(object));
+ }
+
+
+ public int length(Object object) {
+ return coerceToCollection(object).size();
+ }
+
+
+
+
+ public Number add(Object left, Object right) {
+ return adjust(coerceDouble(left) + coerceDouble(right));
+ }
+
+
+ public Number sub(Object left, Object right) {
+ return adjust(coerceDouble(left) - coerceDouble(right));
+ }
+
+
+ public Number mult(Object left, Object right) {
+ return adjust(coerceDouble(left) * coerceDouble(right));
+ }
+
+
+ public int iDiv(Object left, Object right) {
+ return coerceInt(left) / coerceInt(right);
+ }
+
+
+ public int rem(Object left, Object right) {
+ return coerceInt(left) % coerceInt(right);
+ }
+
+
+ public Number div(Object left, Object right) {
+ return adjust(coerceDouble(left) / coerceDouble(right));
+ }
+
+
+ public boolean neq(Object left, Object right) {
+ return !eq(left, right);
+ }
+
+ public boolean strictNeq(Object left, Object right) {
+ return !strictEq(left, right);
+ }
+
+ public boolean gt(Object left, Object right) {
+ return !leq(left, right);
+ }
+
+
+ public boolean geq(Object left, Object right) {
+ return !lt(left, right);
+ }
+
+ public boolean isCollection(Object obj) {
+ return (obj instanceof Collection) || (obj instanceof Object[])
+ || (obj instanceof Iterable)
+ || (obj instanceof Iterator);
+ }
+
+ private double coerceDouble(Object object) {
+ if (object instanceof Number) {
+ return ((Number) object).doubleValue();
+ }
+ return 0;
+ }
+
+ private int coerceInt(Object object) {
+ return coerceNumeric(object).intValue();
+ }
+
+ private Number adjust(double x) {
+ if (Math.floor(x) == x) {
+ return (int)x;
+ }
+ return x;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/ObjectModelImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/ObjectModelImpl.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/ObjectModelImpl.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/ObjectModelImpl.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * 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.common;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.adapter.Adaptable;
+import org.apache.sling.api.resource.ValueMap;
+
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.api.Record;
+import org.apache.sling.scripting.sightly.api.SightlyRenderException;
+
+/**
+ * Default implementation for the object model
+ */
+@Component
+@Service(ObjectModel.class)
+public class ObjectModelImpl implements ObjectModel {
+
+ private static final String TO_STRING_METHOD = "toString";
+
+ @Override
+ public Object resolveProperty(Object target, Object property) {
+ if (property instanceof Number) {
+ return getIndex(target, ((Number) property).intValue());
+ }
+ return getProperty(target, property);
+ }
+
+ @Override
+ public String coerceToString(Object target) {
+ return objectToString(target);
+ }
+
+ @Override
+ public boolean coerceToBoolean(Object object) {
+ return toBoolean(object);
+ }
+
+ @Override
+ public Collection<Object> coerceToCollection(Object object) {
+ return obtainCollection(object);
+ }
+
+ @Override
+ public Map coerceToMap(Object object) {
+ if (object instanceof Map) {
+ return (Map) object;
+ }
+ return Collections.emptyMap();
+ }
+
+
+ @Override
+ public Number coerceNumeric(Object object) {
+ if (object instanceof Number) {
+ return (Number) object;
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean strictEq(Object left, Object right) {
+ if (left instanceof Number && right instanceof Number) {
+ return ((Number) left).doubleValue() == ((Number) right).doubleValue();
+ }
+ if (left instanceof String && right instanceof String) {
+ return left.equals(right);
+ }
+ if (left instanceof Boolean && right instanceof Boolean) {
+ return left.equals(right);
+ }
+ if (left == null && right == null) {
+ return true;
+ }
+ if (left == null || right == null) {
+ Object notNull = (left != null) ? left : right;
+ if (notNull instanceof String || notNull instanceof Boolean || notNull instanceof Number) {
+ return false;
+ }
+ }
+ throw new UnsupportedOperationException("Invalid types in comparison. Equality is supported for String, Number & Boolean types");
+ }
+
+ public boolean lt(Object left, Object right) {
+ if (left instanceof Number && right instanceof Number) {
+ return ((Number) left).doubleValue() < ((Number) right).doubleValue();
+ }
+ throw new UnsupportedOperationException("Invalid types in comparison. Comparison is supported for Number types only");
+ }
+
+
+ public boolean leq(Object left, Object right) {
+ if (left instanceof Number && right instanceof Number) {
+ return ((Number) left).doubleValue() <= ((Number) right).doubleValue();
+ }
+ throw new UnsupportedOperationException("Invalid types in comparison. Comparison is supported for Number types only");
+ }
+
+ @SuppressWarnings("unchecked")
+ private Collection<Object> obtainCollection(Object obj) {
+ if (obj == null) {
+ return Collections.emptyList();
+ }
+ if (obj instanceof Object[]) {
+ return Arrays.asList((Object[]) obj);
+ }
+ if (obj instanceof Collection) {
+ return (Collection<Object>) obj;
+ }
+ if (obj instanceof Map) {
+ return ((Map) obj).keySet();
+ }
+ if (obj instanceof Record) {
+ return ((Record) obj).properties();
+ }
+ if (obj instanceof Enumeration) {
+ return Collections.list((Enumeration<Object>) obj);
+ }
+ if (obj instanceof Iterator) {
+ return fromIterator((Iterator<Object>) obj);
+ }
+ return Collections.emptyList();
+ }
+
+ private Collection<Object> fromIterator(Iterator<Object> iterator) {
+ ArrayList<Object> result = new ArrayList<Object>();
+ while (iterator.hasNext()) {
+ result.add(iterator.next());
+ }
+ return result;
+ }
+
+ private boolean toBoolean(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (obj instanceof Number) {
+ Number number = (Number) obj;
+ //todo should we consider precision issues?
+ return !(number.doubleValue() == 0.0);
+ }
+
+ String s = obj.toString().trim();
+ if ("".equals(s)) {
+ return false;
+ } else if ("true".equalsIgnoreCase(s) || "false".equalsIgnoreCase(s)) {
+ return Boolean.parseBoolean(s);
+ }
+
+ if (obj instanceof Collection) {
+ return ((Collection) obj).size() > 0;
+ }
+
+ if (obj instanceof Map) {
+ return ((Map) obj).size() > 0;
+ }
+
+ if (obj instanceof Iterable<?>) {
+ return ((Iterable<?>) obj).iterator().hasNext();
+ }
+
+ if (obj instanceof Iterator<?>) {
+ return ((Iterator<?>) obj).hasNext();
+ }
+
+ if (obj instanceof Object[]) {
+ return ((Object[]) obj).length > 0;
+ }
+
+ return true;
+ }
+
+ private Object getProperty(Object target, Object propertyObj) {
+ String property = coerceToString(propertyObj);
+ if (StringUtils.isEmpty(property)) {
+ throw new IllegalArgumentException("Invalid property name");
+ }
+ if (target == null) {
+ return null;
+ }
+ Object result = null;
+ if (target instanceof Map) {
+ result = getMapProperty((Map) target, property);
+ }
+ if (result == null && target instanceof Record) {
+ result = ((Record) target).get(property);
+ }
+ if (result == null) {
+ result = getObjectProperty(target, property);
+ }
+ if (result == null && target instanceof Adaptable) {
+ result = getValueMapProperty(((Adaptable) target).adaptTo(ValueMap.class), property);
+ }
+ return result;
+ }
+
+ private Object getIndex(Object obj, int index) {
+ if (obj instanceof Map) {
+ Map map = (Map) obj;
+ if (map.containsKey(index)) {
+ return map.get(index);
+ }
+ }
+ Collection collection = coerceToCollection(obj);
+ if (collection instanceof List) {
+ return getIndexSafe((List) collection, index);
+ }
+ return null;
+ }
+
+ private Object getIndexSafe(List list, int index) {
+ if (index < 0 || index >= list.size()) {
+ return null;
+ }
+ return list.get(index);
+ }
+
+ private Object getValueMapProperty(ValueMap valueMap, String property) {
+ if (valueMap == null) {
+ return null;
+ }
+ return valueMap.get(property);
+ }
+
+ private Object getMapProperty(Map map, String property) {
+ return map.get(property);
+ }
+
+ private Object getObjectProperty(Object obj, String property) {
+ Object result = getObjectNoArgMethod(obj, property);
+ if (result != null) return result;
+ return getField(obj, property);
+ }
+
+ private Object getField(Object obj, String property) {
+ if (obj instanceof Object[] && "length".equals(property)) {
+ // Working around this limitation: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getFields%28%29
+ return ((Object[]) obj).length;
+ }
+ Class<?> cls = obj.getClass();
+ try {
+ Field field = cls.getDeclaredField(property);
+ return field.get(obj);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private Object getObjectNoArgMethod(Object obj, String property) {
+ Class<?> cls = obj.getClass();
+ Method method = findMethod(cls, property);
+ if (method != null) {
+ try {
+ method = extractMethodInheritanceChain(cls, method);
+ return method.invoke(obj);
+ } catch (Exception e) {
+ throw new SightlyRenderException(e);
+ }
+ }
+ return null;
+ }
+
+ private Method findMethod(Class<?> cls, String baseName) {
+ Method method;
+ String capitalized = StringUtils.capitalize(baseName);
+ method = tryMethod(cls, "get" + capitalized);
+ if (method != null) return method;
+ method = tryMethod(cls, "is" + capitalized);
+ if (method != null) return method;
+ method = tryMethod(cls, baseName);
+ return method;
+ }
+
+
+ private Method tryMethod(Class<?> cls, String name) {
+ try {
+ Method m = cls.getMethod(name);
+ Class<?> declaringClass = m.getDeclaringClass();
+ return (isMethodAllowed(m)) ? m : null;
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private boolean isMethodAllowed(Method method) {
+ Class<?> declaringClass = method.getDeclaringClass();
+ //methods of the Object.class are forbidden (except toString, which is allowed)
+ return declaringClass != Object.class || TO_STRING_METHOD.equals(method.getName());
+ }
+
+
+ private String objectToString(Object obj) {
+ String output = "";
+ if (obj != null) {
+ if (obj instanceof String) {
+ output = (String) obj;
+ } else if (isPrimitive(obj)) {
+ output = obj.toString();
+ } else {
+ Collection<?> col = obtainCollection(obj);
+ if (col != null) {
+ output = collectionToString(col);
+ }
+ }
+ }
+ return output;
+ }
+
+ private static final Set<Class<?>> primitiveClasses = primitiveClasses();
+
+ private boolean isPrimitive(Object obj) {
+ return primitiveClasses.contains(obj.getClass());
+ }
+
+ private String collectionToString(Collection<?> col) {
+ StringBuilder builder = new StringBuilder();
+ String prefix = "";
+ for (Object o : col) {
+ builder.append(prefix).append(objectToString(o));
+ prefix = ",";
+ }
+ return builder.toString();
+ }
+
+ private static Set<Class<?>> primitiveClasses() {
+ Set<Class<?>> set = new HashSet<Class<?>>();
+ set.add(Boolean.class);
+ set.add(Character.class);
+ set.add(Byte.class);
+ set.add(Short.class);
+ set.add(Integer.class);
+ set.add(Long.class);
+ set.add(Float.class);
+ set.add(Double.class);
+ set.add(Void.class);
+ return set;
+ }
+
+ private static Method extractMethodInheritanceChain(Class type, Method m) {
+ if (m == null || Modifier.isPublic(type.getModifiers())) {
+ return m;
+ }
+ Class[] inf = type.getInterfaces();
+ Method mp;
+ for (Class<?> iface : inf) {
+ try {
+ mp = iface.getMethod(m.getName(), (Class[]) m.getParameterTypes());
+ mp = extractMethodInheritanceChain(mp.getDeclaringClass(), mp);
+ if (mp != null) {
+ return mp;
+ }
+ } catch (NoSuchMethodException e) {
+ // do nothing
+ }
+ }
+ Class<?> sup = type.getSuperclass();
+ if (sup != null) {
+ try {
+ mp = sup.getMethod(m.getName(), (Class[]) m.getParameterTypes());
+ mp = extractMethodInheritanceChain(mp.getDeclaringClass(), mp);
+ if (mp != null) {
+ return mp;
+ }
+ } catch (NoSuchMethodException e) {
+ // do nothing
+ }
+ }
+ return null;
+ }
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/SightlyRuntimeImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/SightlyRuntimeImpl.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/SightlyRuntimeImpl.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/common/SightlyRuntimeImpl.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.api.ExtensionInstance;
+import org.apache.sling.scripting.sightly.api.RuntimeExtension;
+import org.apache.sling.scripting.sightly.api.RenderContext;
+import org.apache.sling.scripting.sightly.api.SightlyRenderException;
+import org.apache.sling.scripting.sightly.api.SightlyRuntime;
+import org.apache.sling.scripting.sightly.api.ExtensionInstance;
+
+/**
+ * Implementation for apache runtime
+ */
+public class SightlyRuntimeImpl implements SightlyRuntime {
+
+ private final Map<String, RuntimeExtension> mapping;
+ private final Map<String, ExtensionInstance> instanceCache = new HashMap<String, ExtensionInstance>();
+ private RenderContext renderContext;
+
+ public SightlyRuntimeImpl(Map<String, RuntimeExtension> mapping) {
+ this.mapping = mapping;
+ }
+
+ @Override
+ public Object call(String functionName, Object... arguments) {
+ ExtensionInstance instance;
+ instance = instanceCache.get(functionName);
+ if (instance == null) {
+ instance = createInstance(functionName);
+ instanceCache.put(functionName, instance);
+ }
+ return instance.call(arguments);
+ }
+
+ public RenderContext getRenderContext() {
+ return renderContext;
+ }
+
+ public void setRenderContext(RenderContext renderContext) {
+ this.renderContext = renderContext;
+ }
+
+ private ExtensionInstance createInstance(String name) {
+ RuntimeExtension extension = mapping.get(name);
+ if (extension == null) {
+ throw new SightlyRenderException("Runtime extension is not available: " + name);
+ }
+ return extension.provide(renderContext);
+ }
+}