Author: bdelacretaz
Date: Fri Dec 6 16:21:37 2013
New Revision: 1548581
URL: http://svn.apache.org/r1548581
Log:
Use Rhino-specific BindingsValuesProvider
Added:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/GenericBindingsValuesProvider.java
- copied, changed from r1548533,
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextBindingsValuesProvider.java
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoBindingsValuesProvider.java
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoRequestContextAdapter.java
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/ScriptableMap.java
- copied, changed from r1548533,
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/ScriptableProperties.java
Removed:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextBindingsValuesProvider.java
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/ScriptableProperties.java
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/ScriptableResourceProperties.java
Modified:
sling/whiteboard/bdelacretaz/request-context/pom.xml
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/api/SlingRequestContext.java
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextFilter.java
Modified: sling/whiteboard/bdelacretaz/request-context/pom.xml
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/pom.xml?rev=1548581&r1=1548580&r2=1548581&view=diff
==============================================================================
--- sling/whiteboard/bdelacretaz/request-context/pom.xml (original)
+++ sling/whiteboard/bdelacretaz/request-context/pom.xml Fri Dec 6 16:21:37
2013
@@ -62,7 +62,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.scripting.api</artifactId>
- <version>2.1.4</version>
+ <version>2.1.5-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/api/SlingRequestContext.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/api/SlingRequestContext.java?rev=1548581&r1=1548580&r2=1548581&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/api/SlingRequestContext.java
(original)
+++
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/api/SlingRequestContext.java
Fri Dec 6 16:21:37 2013
@@ -18,50 +18,88 @@
*/
package org.apache.sling.requestcontext.api;
+import java.util.HashMap;
+import java.util.Map;
+
import javax.servlet.http.HttpServletRequest;
import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.requestcontext.impl.ScriptableProperties;
-import org.apache.sling.requestcontext.impl.ScriptableResourceProperties;
-import org.mozilla.javascript.Scriptable;
+import org.apache.sling.api.resource.ValueMap;
/** Intelligent Request Context meant to be provided in
* scripts as the "rc" object.
*/
@SuppressWarnings("serial")
-public class SlingRequestContext extends ScriptableProperties {
+public class SlingRequestContext extends HashMap<String, Object> {
private final SlingHttpServletRequest request;
+ private boolean readOnly;
+
+ /** Read-write properties are stored under this key, the rest is read-only
*/
+ public static final String USER_MAP_NAME = "u";
+
+ /** The current Resource's properties are stored under this key */
+ public static final String RESOURCE_VALUEMAP_PROPERTY_NAME = "r";
+
+ /** The name to use to bind this object in scripts */
+ public static final String RC_BINDING_NAME = "rc";
public SlingRequestContext(SlingHttpServletRequest request) {
this.request = request;
request.setAttribute(this.getClass().getName(), this);
- // Free read-write properties: "u"
- put("u", this, new ScriptableProperties());
+ put(USER_MAP_NAME, new HashMap<String, Object>());
// The current resource's properties as "r"
- put("r", this, new
ScriptableResourceProperties(request.getResource()));
+ put(RESOURCE_VALUEMAP_PROPERTY_NAME,
request.getResource().adaptTo(ValueMap.class));
- setReadOnly(true);
+ readOnly = true;
}
public static SlingRequestContext fromRequest(HttpServletRequest r) {
return
(SlingRequestContext)r.getAttribute(SlingRequestContext.class.getName());
}
-
+
@Override
- public Object get(String name, Scriptable start) {
- Object result = super.get(name, start);
- if(result == NOT_FOUND) {
+ public Object get(Object key) {
+ Object result = super.get(key);
+ if(result == null) {
// TODO fallback to request attributes, script bindings, OSGi
services etc
// for now just a few example fallbacks - should use reflection on
objects like Resource
- if("path".equals(name)) {
+ if("path".equals(key)) {
return request.getResource().getPath();
- } else if("resourceType".equals(name)) {
+ } else if("resourceType".equals(key)) {
return request.getResource().getResourceType();
}
}
return result;
}
-}
+
+ private void failIfReadonly() {
+ if(readOnly) {
+ throw new IllegalStateException("Attempt to modify a readonly " +
getClass().getSimpleName());
+ }
+ }
+
+ @Override
+ public Object put(String arg0, Object arg1) {
+ failIfReadonly();
+ return super.put(arg0, arg1);
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends Object> arg0) {
+ failIfReadonly();
+ super.putAll(arg0);
+ }
+
+ @Override
+ public Object remove(Object arg0) {
+ failIfReadonly();
+ return super.remove(arg0);
+ }
+
+ public boolean isReadyOnly() {
+ return readOnly;
+ }
+}
\ No newline at end of file
Copied:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/GenericBindingsValuesProvider.java
(from r1548533,
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextBindingsValuesProvider.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/GenericBindingsValuesProvider.java?p2=sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/GenericBindingsValuesProvider.java&p1=sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextBindingsValuesProvider.java&r1=1548533&r2=1548581&rev=1548581&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextBindingsValuesProvider.java
(original)
+++
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/GenericBindingsValuesProvider.java
Fri Dec 6 16:21:37 2013
@@ -21,6 +21,7 @@ package org.apache.sling.requestcontext.
import javax.script.Bindings;
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.api.SlingHttpServletRequest;
import org.apache.sling.requestcontext.api.SlingRequestContext;
@@ -28,25 +29,34 @@ import org.apache.sling.scripting.api.Bi
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/** Generic BindingsValuesProvider that provides the SlingRequestContext
directly.
+ *
+ * Language-specific BindingsValuesProvider services can be created
+ * if needed to make this "rc" variable easier to use in scripts, as we're
+ * doing for the Rhino scripting engine in this prototype.
+ *
+ * Sling will use more specific providers instead of this one if they
+ * are present.
+ */
@Component
@Service
-public class RequestContextBindingsValuesProvider implements
BindingsValuesProvider {
+@Property(name="context", value="request")
+public class GenericBindingsValuesProvider implements BindingsValuesProvider {
private Logger log = LoggerFactory.getLogger(getClass());
- static final ThreadLocal<SlingHttpServletRequest> requestThreadLocal = new
ThreadLocal<SlingHttpServletRequest>();
- public static final String RC_BINDING_NAME = "rc";
public void addBindings(Bindings b) {
- final SlingHttpServletRequest request = requestThreadLocal.get();
+ final SlingHttpServletRequest request =
RequestContextFilter.getThreadLocalRequest();
if(request == null) {
- log.debug("No request in thread local, cannot add {} binding",
RC_BINDING_NAME);
+ log.debug("No request in thread local, cannot add {} binding",
SlingRequestContext.RC_BINDING_NAME);
return;
}
final SlingRequestContext rc =
SlingRequestContext.fromRequest(request);
if(rc == null) {
- log.debug("No SlingRequestContext in request, cannot add {}
binding", RC_BINDING_NAME);
+ log.debug("No SlingRequestContext in request, cannot add {}
binding", SlingRequestContext.RC_BINDING_NAME);
return;
}
- b.put(RC_BINDING_NAME, rc);
+ log.debug("Binding SlingRequestContext as '{}'",
SlingRequestContext.RC_BINDING_NAME);
+ b.put(SlingRequestContext.RC_BINDING_NAME, rc);
}
}
Modified:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextFilter.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextFilter.java?rev=1548581&r1=1548580&r2=1548581&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextFilter.java
(original)
+++
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/RequestContextFilter.java
Fri Dec 6 16:21:37 2013
@@ -42,19 +42,30 @@ import org.apache.sling.requestcontext.a
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/** Filter that sets up the SlingRequestContextFilter by calling a script
+ * or servlet that's present for the "setup" extension.
+ */
@SlingFilter(
scope=SlingFilterScope.REQUEST,
order=Integer.MIN_VALUE,
description="Calls an optional request setup script and populates the
RequestContext")
public class RequestContextFilter implements Filter {
+ /** Extension to use to resolve setup scripts. TODO: configurable? */
public static final String SETUP_SCRIPT_EXTENSION = "setup";
+ /** Name of the context property for BindingsValuesProviders to use
+ * for our setup script
+ */
+ public static final String BVP_CONTEXT = "setup";
+
private Logger log = LoggerFactory.getLogger(getClass());
@Reference
private ServletResolver servletResolver;
+ static final ThreadLocal<SlingHttpServletRequest> requestThreadLocal = new
ThreadLocal<SlingHttpServletRequest>();
+
private static class RequestPathInfoWrapper implements RequestPathInfo {
private final RequestPathInfo wrapped;
@@ -89,16 +100,15 @@ public class RequestContextFilter implem
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
- SlingHttpServletRequest slingRequest = null;
- if(request instanceof SlingHttpServletRequest) {
- slingRequest = (SlingHttpServletRequest)request;
- setupRequestContext(slingRequest, response);
- }
try {
-
RequestContextBindingsValuesProvider.requestThreadLocal.set(slingRequest);
+ if(request instanceof SlingHttpServletRequest) {
+ final SlingHttpServletRequest slingRequest =
(SlingHttpServletRequest)request;
+ requestThreadLocal.set(slingRequest);
+ setupRequestContext(slingRequest, response);
+ }
chain.doFilter(request, response);
} finally {
- RequestContextBindingsValuesProvider.requestThreadLocal.set(null);
+ requestThreadLocal.set(null);
}
}
@@ -111,6 +121,7 @@ public class RequestContextFilter implem
return;
}
+ new SlingRequestContext(slingRequest);
final SlingHttpServletResponse slingResponse =
(SlingHttpServletResponse)servletResponse;
// Wrap the request so that we resolve a script for the setup extension
@@ -133,13 +144,14 @@ public class RequestContextFilter implem
bindings.setRequest(slingRequest);
bindings.setResource(slingRequest.getResource());
bindings.setResponse(slingResponse);
- final SlingRequestContext rc = new
SlingRequestContext(slingRequest);
- bindings.put("rc", rc);
- log.debug("Executing {} to populate {}", script, rc);
+ log.debug("Executing {} to populate request context", script);
script.eval(bindings);
} else {
log.debug("{} does not implement SlingScript, cannot use it to
setup RequestContext");
}
}
+ public static SlingHttpServletRequest getThreadLocalRequest() {
+ return requestThreadLocal.get();
+ }
}
Added:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoBindingsValuesProvider.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoBindingsValuesProvider.java?rev=1548581&view=auto
==============================================================================
---
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoBindingsValuesProvider.java
(added)
+++
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoBindingsValuesProvider.java
Fri Dec 6 16:21:37 2013
@@ -0,0 +1,64 @@
+/*
+ * 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.requestcontext.impl.rhino;
+
+import javax.script.Bindings;
+import javax.script.ScriptEngine;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.requestcontext.api.SlingRequestContext;
+import org.apache.sling.requestcontext.impl.RequestContextFilter;
+import org.apache.sling.scripting.api.BindingsValuesProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Language-specific BindingsValuesProvider that provides the
SlingRequestContext
+ * for Rhino scripts. */
+@Component
+@Service
+@Properties({
+ @Property(name="context", value="request"),
+ @Property(name=ScriptEngine.NAME, value={"js","ecma","javascript"})
+})
+public class RhinoBindingsValuesProvider implements BindingsValuesProvider {
+
+ /** The name of the script engine to which these bindings apply */
+ public static final String SCRIPT_ENGINE_NAME = "js";
+
+ private Logger log = LoggerFactory.getLogger(getClass());
+
+ public void addBindings(Bindings b) {
+ final SlingHttpServletRequest request =
RequestContextFilter.getThreadLocalRequest();
+ if(request == null) {
+ log.debug("No request in thread local, cannot add {} binding",
SlingRequestContext.RC_BINDING_NAME);
+ return;
+ }
+ final SlingRequestContext rc =
SlingRequestContext.fromRequest(request);
+ if(rc == null) {
+ log.debug("No SlingRequestContext in request, cannot add {}
binding", SlingRequestContext.RC_BINDING_NAME);
+ return;
+ }
+ log.debug("Binding SlingRequestContext as '{}' for the Rhino engine",
SlingRequestContext.RC_BINDING_NAME);
+ b.put(SlingRequestContext.RC_BINDING_NAME, new
RhinoRequestContextAdapter(rc));
+ }
+}
Added:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoRequestContextAdapter.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoRequestContextAdapter.java?rev=1548581&view=auto
==============================================================================
---
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoRequestContextAdapter.java
(added)
+++
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/RhinoRequestContextAdapter.java
Fri Dec 6 16:21:37 2013
@@ -0,0 +1,64 @@
+/*
+ * 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.requestcontext.impl.rhino;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.requestcontext.api.SlingRequestContext;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+/** Scriptable adapter used to provide the {@link SlingRequestContext}
+ * to Rhino scripts
+ */
+@SuppressWarnings("serial")
+public final class RhinoRequestContextAdapter extends ScriptableObject {
+
+ private final SlingRequestContext context;
+
+ public RhinoRequestContextAdapter(SlingRequestContext c) {
+ context = c;
+ }
+
+ @Override
+ public String getClassName() {
+ return getClass().getName();
+ }
+
+ public static RhinoRequestContextAdapter fromRequest(HttpServletRequest r)
{
+ return new
RhinoRequestContextAdapter(SlingRequestContext.fromRequest(r));
+ }
+
+ @Override
+ public Object get(String name, Scriptable start) {
+ return wrap(context.get(name));
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private Object wrap(Object o) {
+ // TODO there's a better way to do that with Rhino...minimal prototype
for now
+ if(o instanceof Map) {
+ return new ScriptableMap((Map)o);
+ } else {
+ return o;
+ }
+ }
+}
\ No newline at end of file
Copied:
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/ScriptableMap.java
(from r1548533,
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/ScriptableProperties.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/ScriptableMap.java?p2=sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/ScriptableMap.java&p1=sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/ScriptableProperties.java&r1=1548533&r2=1548581&rev=1548581&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/ScriptableProperties.java
(original)
+++
sling/whiteboard/bdelacretaz/request-context/src/main/java/org/apache/sling/requestcontext/impl/rhino/ScriptableMap.java
Fri Dec 6 16:21:37 2013
@@ -16,41 +16,35 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.requestcontext.impl;
+package org.apache.sling.requestcontext.impl.rhino;
-import java.util.HashMap;
import java.util.Map;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
@SuppressWarnings("serial")
-public class ScriptableProperties extends ScriptableObject {
+public class ScriptableMap extends ScriptableObject {
- private final Map<String, Object> properties = new HashMap<String,
Object>();
- private boolean isReadOnly;
+ private final Map<String, Object> map;
@Override
public String getClassName() {
return getClass().getName();
}
- protected void setReadOnly(boolean b) {
- isReadOnly = b;
+ ScriptableMap(Map<String, Object> m) {
+ map = m;
}
-
+
@Override
public Object get(String name, Scriptable start) {
- final Object result = properties.get(name);
+ final Object result = map.get(name);
return result != null ? result : NOT_FOUND;
}
@Override
public void put(String name, Scriptable start, Object value) {
- if(isReadOnly) {
- throw new IllegalArgumentException("Read-only object, property is
not modifiable:" + name);
- }
- properties.put(name, value);
+ map.put(name, value);
}
-
}