You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2014/11/28 11:18:09 UTC
svn commit: r1642281 [10/14] - in /sling/trunk/contrib/scripting/sightly: ./
engine/ engine/src/main/antlr4/org/apache/sling/parser/expr/generated/
engine/src/main/antlr4/org/apache/sling/scripting/
engine/src/main/antlr4/org/apache/sling/scripting/sig...
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.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.impl.engine.extension.use;
+
+import javax.script.Bindings;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.scripting.sightly.ResourceResolution;
+import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import org.apache.sling.scripting.sightly.impl.engine.UnitLoader;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.use.ProviderOutcome;
+import org.apache.sling.scripting.sightly.use.SightlyUseException;
+import org.apache.sling.scripting.sightly.use.UseProvider;
+import org.osgi.framework.Constants;
+
+/**
+ * Interprets identifiers as paths to other Sightly templates
+ */
+@Component(
+ metatype = true,
+ label = "Apache Sling Scripting Sightly Render Unit Use Provider",
+ description = "The Render Unit Use Provider is responsible for instantiating Sightly templates through the Use-API."
+)
+@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 = 100,
+ propertyPrivate = false
+ )
+})
+public class RenderUnitProvider implements UseProvider {
+
+ @Reference
+ private UnitLoader unitLoader = null;
+
+ @Reference
+ private ResourceResolverFactory rrf = null;
+
+ @Override
+ public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
+ if (identifier.endsWith("." + SightlyScriptEngineFactory.EXTENSION)) {
+ Bindings globalBindings = renderContext.getBindings();
+ Resource renderUnitResource = locateResource(globalBindings, identifier);
+ RenderUnit renderUnit = unitLoader.createUnit(renderUnitResource, globalBindings, (RenderContextImpl) renderContext);
+ return ProviderOutcome.notNullOrFailure(renderUnit);
+ }
+ return ProviderOutcome.failure();
+ }
+
+ private Resource locateResource(Bindings bindings, String script) {
+ ResourceResolver adminResolver = null;
+ try {
+ adminResolver = rrf.getAdministrativeResourceResolver(null);
+ SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST);
+ SlingScriptHelper ssh = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
+ Resource resource = ResourceResolution.resolveComponentForRequest(adminResolver, request);
+ if (resource != null) {
+ return ResourceResolution.resolveComponentRelative(adminResolver, resource, script);
+ } else {
+ return ResourceResolution.resolveComponentRelative(adminResolver, ssh.getScript().getScriptResource(), script);
+ }
+ } catch (LoginException e) {
+ throw new SightlyUseException(e);
+ } finally {
+ if (adminResolver != null) {
+ adminResolver.close();
+ }
+ }
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.engine.extension.use;
+
+import javax.script.Bindings;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.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.api.scripting.SlingScript;
+import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.use.ProviderOutcome;
+import org.apache.sling.scripting.sightly.use.SightlyUseException;
+import org.apache.sling.scripting.sightly.use.UseProvider;
+import org.osgi.framework.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Use provider that interprets the identifier as a script path, and runs the respective script using a script engine that matches the
+ * script extension.
+ *
+ * This provider returns a non-failure outcome only if the evaluated script actually returns something. For more details check the
+ * implementation of the {@link SlingScript#eval(SlingBindings)} method for the available script engines from your platform.
+ */
+@Component(
+ metatype = true,
+ label = "Apache Sling Scripting Sightly Script Use Provider",
+ description = "The Script Use Provider is responsible for instantiating objects from scripts evaluated by other Sling Scripting " +
+ "Engines."
+)
+@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 = 0,
+ propertyPrivate = false
+ )
+})
+public class ScriptUseProvider implements UseProvider {
+
+ private static final Logger log = LoggerFactory.getLogger(ScriptUseProvider.class);
+
+ @Reference
+ private ResourceResolverFactory rrf = null;
+
+ @Override
+ public ProviderOutcome provide(String scriptName, RenderContext renderContext, Bindings arguments) {
+ Bindings globalBindings = renderContext.getBindings();
+ Bindings bindings = UseProviderUtils.merge(globalBindings, arguments);
+ String extension = scriptExtension(scriptName);
+ if (extension == null || extension.equals(SightlyScriptEngineFactory.EXTENSION)) {
+ return ProviderOutcome.failure();
+ }
+ SlingScriptHelper sling = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
+ ResourceResolver adminResolver = null;
+ try {
+ adminResolver = rrf.getAdministrativeResourceResolver(null);
+ if (adminResolver == null) {
+ log.warn("Cannot obtain administrative resource resolver for " + scriptName);
+ return ProviderOutcome.failure();
+ }
+ Resource scriptResource = UseProviderUtils.locateScriptResource(adminResolver, sling, scriptName);
+ if (scriptResource == null) {
+ log.debug("Path does not match an existing resource: {}", scriptName);
+ return ProviderOutcome.failure();
+ }
+ return evalScript(scriptResource, bindings);
+ } catch (LoginException e) {
+ throw new SightlyUseException(e);
+ } finally {
+ if (adminResolver != null) {
+ adminResolver.close();
+ }
+ }
+
+ }
+
+ private ProviderOutcome evalScript(Resource scriptResource, Bindings bindings) {
+ SlingScript slingScript = scriptResource.adaptTo(SlingScript.class);
+ if (slingScript == null) {
+ return ProviderOutcome.failure();
+ }
+ SlingBindings slingBindings = new SlingBindings();
+ slingBindings.putAll(bindings);
+ Object scriptEval = slingScript.eval(slingBindings);
+ return ProviderOutcome.notNullOrFailure(scriptEval);
+ }
+
+ private String scriptExtension(String path) {
+ String extension = StringUtils.substringAfterLast(path, ".");
+ if (StringUtils.isEmpty(extension)) {
+ extension = null;
+ }
+ return extension;
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseProviderUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseProviderUtils.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseProviderUtils.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseProviderUtils.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.engine.extension.use;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.scripting.sightly.ResourceResolution;
+import org.apache.sling.scripting.sightly.use.SightlyUseException;
+import org.apache.sling.scripting.sightly.use.UseProvider;
+
+/**
+ * Helper class for {@link UseProvider} implementations.
+ */
+public class UseProviderUtils {
+
+ /**
+ * Combine two bindings objects. Priority goes to latter bindings.
+ *
+ * @param former first map of bindings
+ * @param latter second map of bindings, which can override the fist one
+ * @return the merging of the two maps
+ */
+ public static Bindings merge(Bindings former, Bindings latter) {
+ Bindings bindings = new SimpleBindings();
+ bindings.putAll(former);
+ bindings.putAll(latter);
+ return bindings;
+ }
+
+ /**
+ * Retrieves the {@link SlingScriptHelper} from a {@link Bindings} map.
+ *
+ * @param bindings the bindings map
+ * @return the {@link SlingScriptHelper} if found, {@code null} otherwise
+ */
+ public static SlingScriptHelper getHelper(Bindings bindings) {
+ return (SlingScriptHelper) bindings.get(SlingBindings.SLING);
+ }
+
+ /**
+ * Locates a script resource identified by the {@code script} path. This path can be absolute or relative. If the path is relative
+ * then it will be used to locate a script for the current request, provided by the {@link SlingScriptHelper} parameter.
+ *
+ * @param resourceResolver a resource resolver used for searching the script
+ * @param sling the {@link SlingScriptHelper}
+ * @param script the path to the script
+ * @return the script resource if found, {@code null} otherwise
+ */
+ public static Resource locateScriptResource(ResourceResolver resourceResolver, SlingScriptHelper sling, String script) {
+ Resource result = null;
+ if (script.startsWith("/")) {
+ result = resourceResolver.getResource(script);
+ }
+ if (result == null) {
+ Resource componentResource = ResourceResolution.resolveComponentForRequest(resourceResolver, sling.getRequest());
+ result = ResourceResolution.resolveComponentRelative(resourceResolver, componentResource, script);
+ }
+ if (result != null) {
+ checkSearchPath(result, resourceResolver);
+ }
+ return result;
+ }
+
+ private static void checkSearchPath(Resource resource, ResourceResolver resourceResolver) {
+ String resourcePath = resource.getPath();
+ for (String path : resourceResolver.getSearchPath()) {
+ if (resourcePath.startsWith(path)) {
+ return;
+ }
+ }
+ throw new SightlyUseException("Use plugin cannot access path: " + resource.getPath());
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseProviderUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.engine.extension.use;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.scripting.sightly.extension.ExtensionInstance;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtensionException;
+import org.apache.sling.scripting.sightly.impl.plugin.UsePlugin;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.use.ProviderOutcome;
+import org.apache.sling.scripting.sightly.use.SightlyUseException;
+import org.apache.sling.scripting.sightly.use.UseProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Runtime extension for the USE plugin
+ */
+@Component
+@Service(RuntimeExtension.class)
+@Properties(
+ @Property(name = RuntimeExtension.SCR_PROP_NAME, value = UsePlugin.FUNCTION_NAME)
+)
+@Reference(
+ policy = ReferencePolicy.DYNAMIC,
+ referenceInterface = UseProvider.class,
+ name = "useProvider",
+ cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE
+)
+public class UseRuntimeExtension implements RuntimeExtension {
+
+ private final Map<ServiceReference, UseProvider> providersMap = new ConcurrentSkipListMap<ServiceReference, UseProvider>();
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public ExtensionInstance provide(final RenderContext renderContext) {
+ return new ExtensionInstance() {
+
+ @Override
+ public Object call(Object... arguments) {
+ if (arguments.length != 2) {
+ throw new RuntimeExtensionException("Use extension requires two arguments");
+ }
+ String identifier = renderContext.toString(arguments[0]);
+ if (StringUtils.isEmpty(identifier)) {
+ return null;
+ }
+ Map<String, Object> useArgumentsMap = renderContext.toMap(arguments[1]);
+ Bindings useArguments = new SimpleBindings(Collections.unmodifiableMap(useArgumentsMap));
+ ArrayList<UseProvider> providers = new ArrayList<UseProvider>(providersMap.values());
+ ListIterator<UseProvider> iterator = providers.listIterator(providers.size());
+ while (iterator.hasPrevious()) {
+ UseProvider provider = iterator.previous();
+ ProviderOutcome outcome = provider.provide(identifier, renderContext, useArguments);
+ if (outcome.isSuccess()) {
+ return outcome.getResult();
+ }
+ }
+ throw new SightlyUseException("No use provider could resolve identifier: " + identifier);
+ }
+ };
+ }
+
+ // OSGi ################################################################################################################################
+
+ @SuppressWarnings("UnusedDeclaration")
+ private void bindUseProvider(ServiceReference serviceReference) {
+ BundleContext bundleContext = serviceReference.getBundle().getBundleContext();
+ providersMap.put(serviceReference, (UseProvider) bundleContext.getService(serviceReference));
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ private void unbindUseProvider(ServiceReference serviceReference) {
+ providersMap.remove(serviceReference);
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,418 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.engine.runtime;
+
+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.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.script.Bindings;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.adapter.Adaptable;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.scripting.sightly.Record;
+import org.apache.sling.scripting.sightly.extension.ExtensionInstance;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Rendering context for Sightly rendering units.
+ * @see RenderUnit
+ */
+public class RenderContextImpl implements RenderContext {
+
+ public static final String TO_STRING_METHOD = "toString";
+ public static final String PROPERTY_ACCESS = "resolveProperty";
+ public static final String COLLECTION_COERCE = "toCollection";
+ public static final String NUMERIC_COERCE = "toNumber";
+ public static final String STRING_COERCE = "toString";
+ public static final String BOOLEAN_COERCE = "toBoolean";
+
+
+ private final Bindings bindings;
+ private final Map<String, RuntimeExtension> mapping;
+ private final Map<String, ExtensionInstance> instanceCache = new HashMap<String, ExtensionInstance>();
+
+ public RenderContextImpl(Bindings bindings, Map<String, RuntimeExtension> mapping) {
+ this.bindings = bindings;
+ this.mapping = mapping;
+ }
+
+ /**
+ * Provide the bindings for this script
+ * @return - the list of global bindings available to the script
+ */
+ @Override
+ public Bindings getBindings() {
+ return bindings;
+ }
+
+ @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);
+ }
+
+ 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(this);
+ }
+
+ @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 toString(Object target) {
+ return objectToString(target);
+ }
+
+ @Override
+ public boolean toBoolean(Object object) {
+ return toBooleanInternal(object);
+ }
+
+ @Override
+ public Collection<Object> toCollection(Object object) {
+ return obtainCollection(object);
+ }
+
+ @Override
+ public Map toMap(Object object) {
+ if (object instanceof Map) {
+ return (Map) object;
+ }
+ return Collections.emptyMap();
+ }
+
+
+ @Override
+ public Number toNumber(Object object) {
+ if (object instanceof Number) {
+ return (Number) object;
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean isCollection(Object obj) {
+ return (obj instanceof Collection) || (obj instanceof Object[])
+ || (obj instanceof Iterable)
+ || (obj instanceof Iterator);
+ }
+
+ @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 toBooleanInternal(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 = toString(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 = toCollection(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(), 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(), m.getParameterTypes());
+ mp = extractMethodInheritanceChain(mp.getDeclaringClass(), mp);
+ if (mp != null) {
+ return mp;
+ }
+ } catch (NoSuchMethodException e) {
+ // do nothing
+ }
+ }
+ return null;
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderUnit.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderUnit.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderUnit.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderUnit.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.engine.runtime;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.scripting.sightly.Record;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Basic unit of rendering. This also extends the record interface. The properties for a unit are the sub-units.
+ */
+public abstract class RenderUnit implements Record<RenderUnit> {
+
+ private final Map<String, RenderUnit> subTemplates = new HashMap<String, RenderUnit>();
+
+ private Map<String, RenderUnit> siblings;
+
+ /**
+ * Render the main script template
+ * @param renderContext - the rendering context
+ * @param arguments - the arguments for this unit
+ */
+ public final void render(RenderContext renderContext, Bindings arguments) {
+ Bindings globalBindings = renderContext.getBindings();
+ PrintWriter writer = (PrintWriter) globalBindings.get(SlingBindings.OUT);
+ render(writer, buildGlobalScope(globalBindings), new CaseInsensitiveBindings(arguments), (RenderContextImpl) renderContext);
+ }
+
+ @Override
+ public RenderUnit get(String name) {
+ return subTemplates.get(name.toLowerCase());
+ }
+
+ @Override
+ public Set<String> properties() {
+ return subTemplates.keySet();
+ }
+
+ protected abstract void render(PrintWriter writer,
+ Bindings bindings,
+ Bindings arguments,
+ RenderContextImpl renderContext);
+
+ @SuppressWarnings({"unused", "unchecked"})
+ protected void callUnit(RenderContext renderContext, Object templateObj, Object argsObj) {
+ if (!(templateObj instanceof RenderUnit)) {
+ return;
+ }
+ RenderUnit unit = (RenderUnit) templateObj;
+ SlingScriptHelper ssh = (SlingScriptHelper) renderContext.getBindings().get(SlingBindings.SLING);
+ Map<String, Object> argumentsMap = renderContext.toMap(argsObj);
+ Bindings arguments = new SimpleBindings(Collections.unmodifiableMap(argumentsMap));
+ unit.render(renderContext, arguments);
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ protected FluentMap obj() {
+ return new FluentMap();
+ }
+
+ protected final void addSubTemplate(String name, RenderUnit renderUnit) {
+ renderUnit.setSiblings(subTemplates);
+ subTemplates.put(name.toLowerCase(), renderUnit);
+ }
+
+ private void setSiblings(Map<String, RenderUnit> siblings) {
+ this.siblings = siblings;
+ }
+
+ private Bindings buildGlobalScope(Bindings bindings) {
+ SimpleBindings simpleBindings = new SimpleBindings(bindings);
+ simpleBindings.putAll(bindings);
+ if (siblings != null) {
+ simpleBindings.putAll(siblings);
+ }
+ simpleBindings.putAll(subTemplates);
+ return new CaseInsensitiveBindings(simpleBindings);
+ }
+
+ protected static class FluentMap extends HashMap<String, Object> {
+
+ /**
+ * Fluent variant of put
+ * @param name - the name of the property
+ * @param value - the value of the property
+ * @return - this instance
+ */
+ public FluentMap with(String name, Object value) {
+ put(name, value);
+ return this;
+ }
+
+ }
+
+ private static final class CaseInsensitiveBindings extends SimpleBindings {
+
+ private CaseInsensitiveBindings(Map<String, Object> m) {
+ for (Map.Entry<String, Object> entry : m.entrySet()) {
+ put(entry.getKey().toLowerCase(), entry.getValue());
+ }
+ }
+
+ @Override
+ public Object get(Object key) {
+ if (!(key instanceof String)) {
+ throw new ClassCastException("key should be a String");
+ }
+ return super.get(((String) key).toLowerCase());
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ if (!(key instanceof String)) {
+ throw new ClassCastException("key should be a String");
+ }
+ return super.containsKey(((String) key).toLowerCase());
+ }
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderUnit.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/SightlyRenderException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/SightlyRenderException.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/SightlyRenderException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/SightlyRenderException.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.engine.runtime;
+
+import org.apache.sling.scripting.sightly.SightlyException;
+
+/**
+ * Exceptions generated by Sightly during runtime
+ */
+public class SightlyRenderException extends SightlyException {
+
+ public SightlyRenderException() {
+ }
+
+ public SightlyRenderException(String message) {
+ super(message);
+ }
+
+ public SightlyRenderException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SightlyRenderException(Throwable cause) {
+ super(cause);
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/SightlyRenderException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.filter;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+
+/**
+ * A filter is a transformation which performs modifications on expressions. Unlike plugins, filters
+ * are always applied on an expression. Whether the filter transformation is actually necessary is
+ * decided by the filter. The application order of filters is given by filter priority.
+ */
+public interface Filter extends Comparable<Filter> {
+
+ /**
+ * Transform the given expression
+ * @param expression the original expression
+ * @return a transformed expression. If the filter is not applicable
+ * to the given expression, then the original expression shall be returned
+ */
+ Expression apply(Expression expression);
+
+ /**
+ * The priority with which filters are applied. This establishes order between filters. Filters with
+ * lower priority are applied first.
+ * @return an integer representing the filter's priority
+ */
+ int priority();
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FilterComponent.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FilterComponent.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FilterComponent.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FilterComponent.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.filter;
+
+import java.util.Dictionary;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * Filters implemented as components.
+ */
+public abstract class FilterComponent implements Filter {
+
+ public static final String PRIORITY = "org.apache.sling.scripting.sightly.impl.filter.priority";
+ public static final int DEFAULT_PRIORITY = 100;
+
+ private int priority = DEFAULT_PRIORITY;
+
+ @Override
+ public int priority() {
+ return priority;
+ }
+
+ @Override
+ public int compareTo(Filter o) {
+ if (this.priority < o.priority()) {
+ return -1;
+ } else if (this.priority == o.priority()) {
+ return 0;
+ }
+ return 1;
+ }
+
+ @Activate
+ protected void activate(ComponentContext componentContext) {
+ Dictionary properties = componentContext.getProperties();
+ priority = PropertiesUtil.toInteger(properties.get(PRIORITY), DEFAULT_PRIORITY);
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FilterComponent.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.filter;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.scripting.sightly.extension.ExtensionInstance;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtensionException;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Implementation for the format filter & runtime support.
+ */
+@Component
+@Service({Filter.class, RuntimeExtension.class})
+@Properties({
+ @Property(name = RuntimeExtension.SCR_PROP_NAME, value = FormatFilter.FORMAT_FUNCTION)
+})
+public class FormatFilter extends FilterComponent implements RuntimeExtension {
+
+ public static final String FORMAT_OPTION = "format";
+ public static final String FORMAT_FUNCTION = "format";
+
+ private static final Pattern PLACEHOLDER_REGEX = Pattern.compile("\\{\\d}");
+
+ @Override
+ public Expression apply(Expression expression) {
+ //todo: if the expression is a string constant, we can produce the transformation at
+ //compile time, with no need of a runtime function
+ if (!expression.containsOption(FORMAT_OPTION)) {
+ return expression;
+ }
+ ExpressionNode argNode = expression.getOption(FORMAT_OPTION);
+ ExpressionNode formattedNode = new RuntimeCall(FORMAT_FUNCTION, expression.getRoot(), argNode);
+ return expression.withNode(formattedNode).removeOptions(FORMAT_OPTION);
+ }
+
+ @Override
+ public ExtensionInstance provide(final RenderContext renderContext) {
+
+ return new ExtensionInstance() {
+ @Override
+ public Object call(Object... arguments) {
+ if (arguments.length != 2) {
+ throw new RuntimeExtensionException("Format function must be called with two arguments");
+ }
+ String source = renderContext.toString(arguments[0]);
+ Object[] params = decodeParams(arguments[1]);
+ return replace(source, params);
+ }
+
+ private Object[] decodeParams(Object paramObj) {
+ if (renderContext.isCollection(paramObj)) {
+ return renderContext.toCollection(paramObj).toArray();
+ }
+ return new Object[] {paramObj};
+ }
+
+ private String replace(String source, Object[] params) {
+ Matcher matcher = PLACEHOLDER_REGEX.matcher(source);
+ StringBuilder builder = new StringBuilder();
+ int lastPos = 0;
+ boolean matched = true;
+ while (matched) {
+ matched = matcher.find();
+ if (matched) {
+ int paramIndex = placeholderIndex(matcher.group());
+ String replacement = param(params, paramIndex);
+ int matchStart = matcher.start();
+ int matchEnd = matcher.end();
+ builder.append(source, lastPos, matchStart).append(replacement);
+ lastPos = matchEnd;
+ }
+ }
+ builder.append(source, lastPos, source.length());
+ return builder.toString();
+ }
+
+ private String param(Object[] params, int index) {
+ if (index >= 0 && index < params.length) {
+ return renderContext.toString(params[index]);
+ }
+ return "";
+ }
+
+ private int placeholderIndex(String placeholder) {
+ return Integer.parseInt(placeholder.substring(1, placeholder.length() - 1));
+ }
+ };
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.filter;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+
+/**
+ * Filter for i18n translation
+ */
+@Component
+@Service(Filter.class)
+@Property(name = FilterComponent.PRIORITY, intValue = 90)
+public class I18nFilter extends FilterComponent {
+
+ public static final String FUNCTION = "i18nTranslation";
+
+ public static final String I18N_OPTION = "i18n";
+ public static final String HINT_OPTION = "hint";
+ public static final String LOCALE_OPTION = "locale";
+
+ @Override
+ public Expression apply(Expression expression) {
+ if (!expression.containsOption(I18N_OPTION)) {
+ return expression;
+ }
+ ExpressionNode hint = option(expression, HINT_OPTION);
+ ExpressionNode locale = option(expression, LOCALE_OPTION);
+ ExpressionNode translation = new RuntimeCall(FUNCTION, expression.getRoot(), locale, hint);
+ return expression.withNode(translation).removeOptions(HINT_OPTION, LOCALE_OPTION);
+ }
+
+ private ExpressionNode option(Expression expression, String optionName) {
+ ExpressionNode node = expression.getOption(optionName);
+ if (node == null) {
+ return NullLiteral.INSTANCE;
+ }
+ return node;
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.filter;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.scripting.sightly.extension.ExtensionInstance;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
+import org.apache.sling.scripting.sightly.extension.RuntimeExtensionException;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Filter providing support for the {@code join} option applied to arrays.
+ */
+@Component
+@Service({Filter.class, RuntimeExtension.class})
+@Properties({
+ @Property(name = RuntimeExtension.SCR_PROP_NAME, value = JoinFilter.JOIN_FUNCTION)
+})
+public class JoinFilter extends FilterComponent implements RuntimeExtension {
+
+ public static final String JOIN_OPTION = "join";
+ public static final String JOIN_FUNCTION = "join";
+
+ @Override
+ public Expression apply(Expression expression) {
+ if (!expression.containsOption(JOIN_OPTION)) {
+ return expression;
+ }
+ ExpressionNode argumentNode = expression.getOption(JOIN_OPTION);
+ ExpressionNode joinResult = new RuntimeCall(JOIN_FUNCTION, expression.getRoot(), argumentNode);
+ return expression.withNode(joinResult).removeOptions(JOIN_OPTION);
+ }
+
+ @Override
+ public ExtensionInstance provide(final RenderContext renderContext) {
+
+ return new ExtensionInstance() {
+ @Override
+ public Object call(Object... arguments) {
+ if (arguments.length != 2) {
+ throw new RuntimeExtensionException("Join function must be called with two arguments.");
+ }
+ Collection<?> collection = renderContext.toCollection(arguments[0]);
+ String joinString = renderContext.toString(arguments[1]);
+ return join(collection, joinString);
+ }
+
+ private String join(Collection<?> collection, String joinString) {
+ StringBuilder sb = new StringBuilder();
+ Iterator<?> iterator = collection.iterator();
+ while (iterator.hasNext()) {
+ String element = renderContext.toString(iterator.next());
+ sb.append(element);
+ if (iterator.hasNext()) {
+ sb.append(joinString);
+ }
+ }
+ return sb.toString();
+ }
+ };
+
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.filter;
+
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+
+/**
+ * XSS filter implementation
+ */
+@Component
+@Service(Filter.class)
+@Property(name = FilterComponent.PRIORITY, intValue = 110)
+public class XSSFilter extends FilterComponent {
+
+ public static final String FUNCTION_NAME = "xss";
+
+ @Override
+ public Expression apply(Expression expression) {
+ ExpressionNode node = expression.getRoot();
+ Map<String, ExpressionNode> options = expression.getOptions();
+ ExpressionNode context = options.get(Syntax.CONTEXT_OPTION);
+ if (context != null) {
+ return new Expression(new RuntimeCall(FUNCTION_NAME, node, context), options);
+ }
+ return expression;
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/MarkupUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/MarkupUtils.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/MarkupUtils.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/MarkupUtils.java Fri Nov 28 10:18:01 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.impl.html;
+
+import java.util.regex.Pattern;
+
+/**
+ * Utility methods related to markup
+ */
+public class MarkupUtils {
+
+ private static final Pattern ATTRIBUTE_BLACKLIST = Pattern.compile("^(style|(on.*))$", Pattern.CASE_INSENSITIVE);
+
+ /**
+ * Attributes which should not be generated by Sightly
+ * @param name the name of the attribute
+ * @return if the attribute is sensitive or not
+ */
+ public static boolean isSensitiveAttribute(String name) {
+ return ATTRIBUTE_BLACKLIST.matcher(name).matches();
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/MarkupUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/AttributeList.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/AttributeList.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/AttributeList.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/AttributeList.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.html.dom;
+
+import java.util.Iterator;
+
+/**
+ * Contains the list of attributes inside an HTML tag.
+ */
+public interface AttributeList {
+
+ /**
+ * Return the count of attributes
+ * @return count of attributes
+ */
+ int attributeCount();
+
+ /**
+ * Return the list of attribute names
+ * @return <code>Iterator</code> iterating over the attribute names
+ */
+ Iterator<String> attributeNames();
+
+ /**
+ * Return a flag indicating whether a specified attribute exists
+ * @return <code>true</code> if the specified attribute exists,
+ * <code>false</code> otherwise
+ */
+ boolean containsAttribute(String name);
+
+ /**
+ * Return an attribute's value, given its name or <code>null</code>
+ * if the attribute cannot be found.
+ * @param name attribute name
+ * @return an attribute's value
+ */
+ String getValue(String name);
+
+ /**
+ * Return an attribute's quote character, given its name or <code>0</code>
+ * if the attribute cannot be found.
+ * @param name attribute name
+ * @return an attribute's quote character
+ */
+ char getQuoteChar(String name);
+
+ /**
+ * Return an attribute's value, already surrounded with the quotes
+ * originally in place. Returns <code>null</code> if the attribute
+ * cannot be found
+ * @param name attribute name
+ * @return an attribute's value
+ */
+ String getQuotedValue(String name);
+
+ /**
+ * Set an attribute's value. If the value is <code>null</code>, this
+ * is semantically different to a {@link #removeValue(String)}.
+ *
+ * @param name attribute name
+ * @param value attribute value
+ */
+ void setValue(String name, String value);
+
+ /**
+ * Remove an attribute's value.
+ * @param name attribute name
+ */
+ void removeValue(String name);
+
+ /**
+ * Return a flag indicating whether this object was modified.
+ * @return <code>true</code> if the object was modified
+ * <code>false</code> otherwise
+ */
+ boolean isModified();
+}
\ No newline at end of file
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/AttributeList.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/DocumentHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/DocumentHandler.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/DocumentHandler.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/DocumentHandler.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.html.dom;
+
+import java.io.IOException;
+
+
+/**
+ * Invoked by the <code>HTMLParser</code> when elements are scanned.
+ */
+public interface DocumentHandler {
+
+ /**
+ * Receive notification of unparsed character data.
+ */
+ void onCharacters(char[] ch, int off, int len) throws IOException;
+
+ void onComment(String characters) throws IOException;
+
+ /**
+ * Receive notification of the beginning of an element.
+ * @param name tag name
+ * @param attList attribute list
+ * @param endSlash flag indicating whether the element is closed with
+ * an ending slash (xhtml-compliant)
+ */
+ void onStartElement(String name, AttributeList attList, boolean endSlash)
+ throws IOException;
+
+ /**
+ * Receive notification of the end of an element.
+ * @param name tag name
+ */
+ void onEndElement(String name)
+ throws IOException;
+
+ /**
+ * Receive notification of parsing start.
+ */
+ void onStart() throws IOException;
+
+ /**
+ * Receive notification of parsing end.
+ */
+ void onEnd() throws IOException;
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/DocumentHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain