Author: cziegeler
Date: Thu Dec 24 09:09:54 2009
New Revision: 893712
URL: http://svn.apache.org/viewvc?rev=893712&view=rev
Log:
SLING-1236 : Scala Scripting: Make all types of the script arguments visible on
the Scala side. Apply patch from Michael Dürig
Modified:
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngine.java
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngineFactory.java
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaScriptEngineTest.java
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaTestBase.java
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/Bindings.scala
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/ScalaInterpreter.scala
sling/trunk/contrib/scripting/scala/interpreter/src/test/scala/org/apache/sling/scripting/scala/interpreter/InterpreterTest.scala
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/html.scala
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/search.scala
sling/trunk/contrib/scripting/scala/samples/hello-world/src/main/resources/content/apps/helloworld/html.scala
Modified:
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
(original)
+++
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
Thu Dec 24 09:09:54 2009
@@ -35,7 +35,6 @@
import javax.jcr.Value;
import javax.jcr.lock.LockException;
-import org.apache.jackrabbit.util.Text;
import org.apache.sling.commons.mime.MimeTypeService;
import org.apache.sling.engine.SlingSettingsService;
import org.apache.sling.jcr.api.SlingRepository;
@@ -79,7 +78,7 @@
private static final String PROP_PASSWORD_DIGEST_ALGORITHM =
"password.digest.algorithm";
private static final String DEFAULT_PASSWORD_DIGEST_ALGORITHM = "sha1";
private String passwordDigestAlgoritm = null;
-
+
/** default log */
final Logger log = LoggerFactory.getLogger(getClass());
@@ -221,7 +220,7 @@
try {
StringBuffer password = new StringBuffer();
password.append("{").append(passwordDigestAlgoritm).append("}");
- password.append(Text.digest(passwordDigestAlgoritm,
+
password.append(DefaultContentCreator.digest(passwordDigestAlgoritm,
pwd.getBytes("UTF-8")));
return password.toString();
} catch (NoSuchAlgorithmException e) {
@@ -230,7 +229,7 @@
throw new IllegalArgumentException(e.toString());
}
}
-
+
// ---------- SCR Integration ---------------------------------------------
/** Activates this component, called by SCR before registering as a
service */
@@ -247,7 +246,7 @@
} else {
passwordDigestAlgoritm = DEFAULT_PASSWORD_DIGEST_ALGORITHM;
}
-
+
Session session = null;
try {
session = this.getSession();
Modified:
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
(original)
+++
sling/trunk/bundles/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
Thu Dec 24 09:09:54 2009
@@ -20,6 +20,7 @@
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.text.ParseException;
@@ -57,7 +58,6 @@
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.util.Text;
import org.apache.sling.jcr.base.util.AccessControlUtil;
/**
@@ -780,7 +780,7 @@
*/
protected String hashPath(String item) throws RepositoryException {
try {
- String hash = Text.digest("sha1", INSTANCE_SEED + item,
"UTF-8");
+ String hash = digest("sha1", (INSTANCE_SEED +
item).getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < STORAGE_LEVELS; i++) {
sb.append(hash, i * 2, (i * 2) + 2).append("/");
@@ -906,4 +906,33 @@
accessControlManager.setPolicy(resourcePath, updatedAcl);
}
+
+ /**
+ * used for the md5
+ */
+ private static final char[] hexTable = "0123456789abcdef".toCharArray();
+
+ /**
+ * Digest the plain string using the given algorithm.
+ *
+ * @param algorithm The alogrithm for the digest. This algorithm must be
+ * supported by the MessageDigest class.
+ * @param data the data to digest with the given algorithm
+ * @return The digested plain text String represented as Hex digits.
+ * @throws java.security.NoSuchAlgorithmException if the desired algorithm
is not supported by
+ * the MessageDigest class.
+ */
+ public static String digest(String algorithm, byte[] data)
+ throws NoSuchAlgorithmException {
+
+ MessageDigest md = MessageDigest.getInstance(algorithm);
+ byte[] digest = md.digest(data);
+ StringBuffer res = new StringBuffer(digest.length * 2);
+ for (int i = 0; i < digest.length; i++) {
+ byte b = digest[i];
+ res.append(hexTable[(b >> 4) & 15]);
+ res.append(hexTable[b & 15]);
+ }
+ return res.toString();
+ }
}
Modified:
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngine.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngine.java?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngine.java
(original)
+++
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngine.java
Thu Dec 24 09:09:54 2009
@@ -21,10 +21,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -36,15 +34,14 @@
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
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.api.AbstractSlingScriptEngine;
+import org.apache.sling.scripting.scala.interpreter.Bindings;
+import org.apache.sling.scripting.scala.interpreter.Bindings$;
import org.apache.sling.scripting.scala.interpreter.JcrFS;
-import org.apache.sling.scripting.scala.interpreter.ScalaBindings;
import org.apache.sling.scripting.scala.interpreter.ScalaInterpreter;
import org.apache.sling.scripting.scala.interpreter.JcrFS.JcrNode;
import org.slf4j.Logger;
@@ -74,8 +71,7 @@
throw new IllegalArgumentException("Bindings does not contain
script helper object");
}
- TypeHints typeHints = new TypeHints(bindings);
- final ScalaBindings scalaBindings = new ScalaBindings();
+ final Bindings scalaBindings = Bindings$.MODULE$.apply();
for (String name : bindings.keySet()) {
if (name == null) {
log.debug("Bindings contain null key. skipping");
@@ -87,40 +83,28 @@
log.debug("{} has null value. skipping", name);
continue;
}
- Class<?> typeHint = typeHints.getType(name);
- if (typeHint == null) {
- log.debug("{} has no type hint. skipping");
- continue;
- }
- scalaBindings.put(makeIdentifier(name), value, typeHint);
+ scalaBindings.putValue(makeIdentifier(name), value);
}
final JcrNode script = getScriptSource(scriptHelper);
final long scriptMod = script.lastModified();
final String scriptName = getScriptName(scriptHelper);
- Boolean outDated = readLocked(new Callable<Boolean>() {
- public Boolean call() throws Exception {
- return isOutDated(scriptMod, scriptName);
+ // xxx: Scripts need to be compiled everytime.
+ // The preamble for injecting the bindings into the script
+ // dependes on the actual types of the bindings. So effectively
+ // there is a specific script generated for each type of bindings.
+ Reporter result = writeLocked(new Callable<Reporter>() {
+ public Reporter call() throws Exception {
+ return interpreter.compile(scriptName, script,
scalaBindings);
}
});
-
- if (outDated) {
- Reporter result = writeLocked(new Callable<Reporter>() {
- public Reporter call() throws Exception {
- return isOutDated(scriptMod, scriptName)
- ? interpreter.compile(scriptName, script,
scalaBindings)
- : null;
- }
- });
-
- if (result != null && result.hasErrors()) {
- throw new ScriptException(result.toString());
- }
+ if (result != null && result.hasErrors()) {
+ throw new ScriptException(result.toString());
}
- Reporter result = readLocked(new Callable<Reporter>() {
+ result = readLocked(new Callable<Reporter>() {
public Reporter call() throws Exception {
OutputStream outputStream = getOutputStream(context);
Reporter result = interpreter.execute(scriptName,
scalaBindings, getInputStream(context),
@@ -331,68 +315,6 @@
};
}
- @SuppressWarnings("serial")
- private static class TypeHints extends HashMap<String, Class<?>> {
- public static final Class<SlingHttpServletRequest> REQUEST_TYPE =
SlingHttpServletRequest.class;
- public static final Class<SlingHttpServletResponse> RESPONSE_TYPE =
SlingHttpServletResponse.class;
- public static final Class<Reader> READER_TYPE = Reader.class;
- public static final Class<SlingScriptHelper> SLING_TYPE =
SlingScriptHelper.class;
- public static final Class<Resource> RESOURCE_TYPE = Resource.class;
- public static final Class<PrintWriter> OUT_TYPE = PrintWriter.class;
- public static final Class<Boolean> FLUSH_TYPE = Boolean.class;
- public static final Class<Logger> LOG_TYPE = Logger.class;
- public static final Class<Node> NODE_TYPE = Node.class;
-
- private static final java.util.Map<String, Class<?>> TYPES = new
HashMap<String, Class<?>>() {{
- put(SlingBindings.REQUEST, REQUEST_TYPE);
- put(SlingBindings.RESPONSE, RESPONSE_TYPE);
- put(SlingBindings.READER, READER_TYPE);
- put(SlingBindings.SLING, SLING_TYPE);
- put(SlingBindings.RESOURCE, RESOURCE_TYPE);
- put(SlingBindings.OUT, OUT_TYPE);
- put(SlingBindings.FLUSH, FLUSH_TYPE);
- put(SlingBindings.LOG, LOG_TYPE);
- put("currentNode", NODE_TYPE);
- }};
-
- public TypeHints(SlingBindings bindings) {
- super();
- for (Object name : bindings.keySet()) {
- setType((String) name, TYPES.get(name));
- }
- }
-
- public void setType(String name, Class<?> type) {
- if (type != null) {
- put(name, type);
- }
- }
-
- public Class<?> getType(String name) {
- Class<?> c = get(name);
- return c == null ? Object.class : c;
- }
-
- /**
- * Compile time assertion enforcing type safety
- */
- @SuppressWarnings("unused")
- private static class CompileTimeAssertion {
- static {
- SlingBindings b = new SlingBindings();
- b.setRequest(REQUEST_TYPE.cast(null));
- b.setResponse(RESPONSE_TYPE.cast(null));
- b.setReader(READER_TYPE.cast(null));
- b.setSling(SLING_TYPE.cast(null));
- b.setResource(RESOURCE_TYPE.cast(null));
- b.setOut(OUT_TYPE.cast(null));
- b.setFlush(FLUSH_TYPE.cast(null));
- b.setLog(LOG_TYPE.cast(null));
- }
- }
-
- }
-
}
Modified:
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngineFactory.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngineFactory.java?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngineFactory.java
(original)
+++
sling/trunk/contrib/scripting/scala/engine/src/main/java/org/apache/sling/scripting/scala/engine/ScalaScriptEngineFactory.java
Thu Dec 24 09:09:54 2009
@@ -42,6 +42,7 @@
import org.apache.sling.scripting.scala.interpreter.ScalaInterpreter;
import org.osgi.framework.Bundle;
import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.tools.nsc.Settings;
@@ -56,6 +57,8 @@
* @scr.service
*/
public class ScalaScriptEngineFactory extends AbstractScriptEngineFactory {
+ private static final Logger log =
LoggerFactory.getLogger(ScalaScriptEngineFactory.class);
+
private static final String PATH_SEPARATOR =
System.getProperty("path.separator");
public final static String[] SCALA_SCRIPT_EXTENSIONS = {"scala", "scs"};
@@ -164,7 +167,7 @@
url = bundles[k].getResource("");
}
- if (url != null) { // FIXME: log null values
+ if (url != null) {
if ("file".equals(url.getProtocol())) {
try {
bundleFs[k] = new PlainFile(new File(url.toURI()));
@@ -177,6 +180,9 @@
bundleFs[k] = BundleFS.create(bundles[k]);
}
}
+ else {
+ log.warn("Cannot retreive resources from Bundle {}.
Skipping.", bundles[k].getSymbolicName());
+ }
}
return bundleFs;
}
Modified:
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaScriptEngineTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaScriptEngineTest.java?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaScriptEngineTest.java
(original)
+++
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaScriptEngineTest.java
Thu Dec 24 09:09:54 2009
@@ -28,9 +28,10 @@
import javax.naming.NamingException;
import javax.script.ScriptException;
+import org.apache.sling.scripting.scala.interpreter.Bindings;
+import org.apache.sling.scripting.scala.interpreter.Bindings$;
import org.apache.sling.scripting.scala.interpreter.InterpreterException;
import org.apache.sling.scripting.scala.interpreter.JcrFS;
-import org.apache.sling.scripting.scala.interpreter.ScalaBindings;
import org.apache.sling.scripting.scala.interpreter.JcrFS.JcrNode;
import scala.tools.nsc.io.AbstractFile;
@@ -74,7 +75,7 @@
public void testDefaultPackage() {
String code = "package a { object Testi { print(1 + 2)}}";
try {
- evalScala("Testi", code, new ScalaBindings());
+ evalScala("Testi", code, Bindings$.MODULE$.apply());
}
catch (ScriptException e) {
Throwable cause = e.getCause();
@@ -92,8 +93,8 @@
public void testNodeAccess() throws RepositoryException, NamingException,
ScriptException, InvocationTargetException {
Node n = getTestRootNode();
String code = "package a { class Testi(vars: TestiVars) { import
vars._; print(n.getPath)}}";
- ScalaBindings bindings = new ScalaBindings();
- bindings.put("n", n, Node.class);
+ Bindings bindings = Bindings$.MODULE$.apply();
+ bindings.putValue("n", n);
assertEquals(n.getPath(), evalScala(code, bindings));
}
@@ -101,10 +102,10 @@
JcrNode appDir = JcrFS.create(getAppNode());
AbstractFile srcDir = appDir.subdirectoryNamed("srcdir");
- ScalaBindings bindings = new ScalaBindings();
+ Bindings bindings = Bindings$.MODULE$.apply();
Date time = Calendar.getInstance().getTime();
- bindings.put("msg", "Hello world", String.class);
- bindings.put("time", time, Date.class);
+ bindings.putValue("msg", "Hello world");
+ bindings.putValue("time", time);
AbstractFile src = srcDir.fileNamed("Testi");
PrintWriter writer = new PrintWriter(src.output());
Modified:
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaTestBase.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaTestBase.java?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaTestBase.java
(original)
+++
sling/trunk/contrib/scripting/scala/engine/src/test/java/org/apache/sling/scripting/scala/ScalaTestBase.java
Thu Dec 24 09:09:54 2009
@@ -31,9 +31,9 @@
import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
import org.apache.sling.scripting.scala.engine.BacklogReporter;
import org.apache.sling.scripting.scala.interpreter.Bindings;
+import org.apache.sling.scripting.scala.interpreter.Bindings$;
import org.apache.sling.scripting.scala.interpreter.InterpreterException;
import org.apache.sling.scripting.scala.interpreter.JcrFS;
-import org.apache.sling.scripting.scala.interpreter.ScalaBindings;
import org.apache.sling.scripting.scala.interpreter.ScalaInterpreter;
import org.apache.sling.scripting.scala.interpreter.JcrFS.JcrNode;
@@ -91,7 +91,7 @@
}
protected String evalScala(String code) throws ScriptException {
- Bindings bindings = new ScalaBindings();
+ Bindings bindings = Bindings$.MODULE$.apply();
return evalScala(createScriptName(), code, bindings);
}
@@ -127,7 +127,7 @@
return evalScala(scriptName, code, bindings);
}
- protected String evalScala(String name, AbstractFile src, ScalaBindings
bindings) throws ScriptException {
+ protected String evalScala(String name, AbstractFile src, Bindings
bindings) throws ScriptException {
try {
interpreterOut.reset();
Reporter result = interpreter.interprete(name, src, bindings,
null, interpreterOut);
Modified:
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/Bindings.scala
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/Bindings.scala?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/Bindings.scala
(original)
+++
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/Bindings.scala
Thu Dec 24 09:09:54 2009
@@ -14,90 +14,96 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import scala.collection.Map
-import scala.collection.mutable.HashMap
+import scala.collection._
package org.apache.sling.scripting.scala.interpreter {
/**
- * An argument consists of a value and its type
+ * Bindings of names to Values
*/
-trait Argument[T <: AnyRef] {
+trait Bindings extends Map[String, AnyRef] {
/**
- * @returns the value of this argument
- */
- def getValue: T
-
- /**
- * @returns the type of this argument
- */
- def getType: Class[T]
-}
-
-/**
- * Bindings of names to {...@link Argument}s
- */
-trait Bindings extends Map[String, Argument[_]] {
-
- /**
- * Associate an argument with a name
+ * Associate a value with a name
* @param name
- * @param argument
- * @returns The argument which was previously associated with the
+ * @param value
+ * @returns The value which was previously associated with the
* given name or null if none.
*/
- def put(name: String, argument: Argument[_]): Argument[_]
+ def putValue(name: String, value: AnyRef): AnyRef
/**
- * Associate an argument with a name
- * @param name
- * @param value the value of the {...@link Argument}
- * @param tyqe the type of the {...@link Argument}
- */
- def put[T <: AnyRef](name: String, value: T, tyqe: Class[T]): Argument[_] =
- put(name, new Argument[T] {
- def getValue: T = value
- def getType: Class[T] = tyqe
- })
-
- /**
- * @returns the value of the {...@link Argument} associated with the given
name
+ * @returns the value associated with the given name
* @param name
*/
def getValue(name: String): AnyRef =
get(name) match {
- case Some(a) => a.getValue
+ case Some(a) => a
case None => null
}
+
+ def getViews(clazz: Class[_]) = {
+ def findLeastAccessibleClass(clazz: Class[_]): Class[_] = {
+ if (accessible(clazz)) clazz
+ else findLeastAccessibleClass(clazz.getSuperclass)
+ }
+
+ def getInterfacesUpTo(clazz: Class[_], bound: Class[_]) = {
+ def getInterfacesUpTo(intfs: mutable.Set[Class[_]], clazz: Class[_],
bound: Class[_]): mutable.Set[Class[_]] =
+ if (clazz == bound) intfs
+ else getInterfacesUpTo(intfs ++ clazz.getInterfaces,
clazz.getSuperclass, bound)
+
+ getInterfacesUpTo(mutable.Set.empty, clazz, bound)
+ }
- /**
- * @returns the type of the {...@link Argument} associated with the given
name
- * @param name
- */
- def getType(name: String): Class[_] =
- get(name) match {
- case Some(a) => a.getClass
- case None => null
+ def accessible(clazz: Class[_]) = {
+ try {
+ Class.forName(clazz.getName)
+ true
+ }
+ catch { case _ => false }
}
+
+ val l = findLeastAccessibleClass(clazz)
+ var o = getInterfacesUpTo(clazz, l)
+ var v = Set.empty ++ o
+
+ while (!v.isEmpty) {
+ val w = v.find(_ => true).get
+ val p = w.getInterfaces.filter(accessible)
+ o = o -- p
+ v = v - w ++ p
+ }
+
+ l::o.toList
+ }
}
/**
- * HashMap based default implementation of {...@link Bindings}.
+ * Default implementation of {...@link Bindings} backed by a mutable Map
*/
-class ScalaBindings extends Bindings {
- private val bindings = new HashMap[String, Argument[_]]
-
- def size: Int = bindings.size
- def get(name: String): Option[Argument[_]] = bindings.get(name)
- def elements: Iterator[(String, Argument[_])] = bindings.elements
-
- def put(name: String, argument: Argument[_]): Argument[_] =
- bindings.put(name, argument) match {
+private class BindingsWrapper(map: mutable.Map[String, AnyRef]) extends
Bindings {
+ def size: Int = map.size
+ def get(name: String) = map.get(name)
+ def elements: Iterator[(String, AnyRef)] = map.elements
+
+ def putValue(name: String, value: AnyRef) =
+ map.put(name, value) match {
case Some(a) => a
case None => null
}
+
}
+object Bindings {
+ import _root_.scala.collection.jcl.Conversions.convertMap
+
+ def apply(): Bindings = new BindingsWrapper(new mutable.HashMap)
+ def apply(map: mutable.Map[String, AnyRef]): Bindings = new
BindingsWrapper(map)
+ def apply(map: java.util.Map[String, AnyRef]): Bindings = new
BindingsWrapper(map)
}
+}
+
+
+
Modified:
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/ScalaInterpreter.scala
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/ScalaInterpreter.scala?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/ScalaInterpreter.scala
(original)
+++
sling/trunk/contrib/scripting/scala/interpreter/src/main/scala/org/apache/sling/scripting/scala/interpreter/ScalaInterpreter.scala
Thu Dec 24 09:09:54 2009
@@ -94,8 +94,15 @@
* @param name Full qualified class name
* @return The compounds consisting of the (sub)-packates followed by the
class name
*/
- protected def packetize(name: String): List[String] =
- name.split('.').toList
+ protected def packetize(name: String): List[String] = name.split('.').toList
+
+ /**
+ * Utility method for mangling fully quallfied class names into a valid Scala
+ * identifier.
+ * @param name Full qualified class name
+ * @return A valid Scala identifier
+ */
+ protected def mangle(name: String) = packetize(name).mkString("_")
/**
* Pre processor for wrapping the script such that it becomes a valid Scala
source entity
@@ -108,8 +115,21 @@
*/
@throws(classOf[InterpreterException])
protected def preProcess(name: String, code: String, bindings: Bindings):
String = {
- def bind(arg: (String, Argument[_])) =
- "lazy val " + arg._1 + " = bindings.getValue(\"" + arg._1 +
"\").asInstanceOf[" + arg._2.getType.getName + "]"
+ def bind(arg: (String, AnyRef)) = {
+ val views = bindings.getViews(arg._2.getClass)
+ val className = views.head.getName
+ val implicits =
+ for {
+ view <- views.tail
+ intfName = view.getName
+ methName = mangle(className) + "2" + mangle(intfName)
+ }
+ yield
+ " implicit def " + methName + "(x: " + className + "): " +
intfName + " = x.asInstanceOf[" + intfName + "]"
+
+ " lazy val " + arg._1 + " = bindings.getValue(\"" + arg._1 +
"\").asInstanceOf[" + className + "]" + NL +
+ implicits.mkString(NL)
+ }
val compounds = packetize(name)
Modified:
sling/trunk/contrib/scripting/scala/interpreter/src/test/scala/org/apache/sling/scripting/scala/interpreter/InterpreterTest.scala
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/interpreter/src/test/scala/org/apache/sling/scripting/scala/interpreter/InterpreterTest.scala?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/interpreter/src/test/scala/org/apache/sling/scripting/scala/interpreter/InterpreterTest.scala
(original)
+++
sling/trunk/contrib/scripting/scala/interpreter/src/test/scala/org/apache/sling/scripting/scala/interpreter/InterpreterTest.scala
Thu Dec 24 09:09:54 2009
@@ -19,10 +19,11 @@
import scala.tools.nsc.Settings
import scala.tools.nsc.io.PlainFile
import scala.tools.nsc.reporters.ConsoleReporter
-import org.apache.sling.scripting.scala.Utils.valueOrElse
import java.io.PrintWriter
import javax.jcr.{Session, Repository, Node, SimpleCredentials}
+import org.apache.sling.scripting.scala.Utils.valueOrElse
import org.apache.jackrabbit.core.{TransientRepository}
+import org.apache.sling.scripting.scala.interpreter.Bindings
package org.apache.sling.scripting.scala.interpreter {
@@ -69,10 +70,10 @@
val outdir = new PlainFile(new java.io.File("."))
val interpreter = new ScalaInterpreter(settings, reporter(settings),
outdir)
- val bindings = new ScalaBindings
+ val bindings = Bindings()
val time = java.util.Calendar.getInstance.getTime
- bindings.put("msg", "Hello world", classOf[String])
- bindings.put("time", time, classOf[java.util.Date])
+ bindings.putValue("msg", "Hello world")
+ bindings.putValue("time", time)
val code = "package a { class Testi(vars: TestiVars) {import vars._;
print(msg + \": \" + time)}}"
val name = "a.Testi"
@@ -92,10 +93,10 @@
val srcDir = appDir.subdirectoryNamed("srcdir")
val interpreter = new ScalaInterpreter(settings, reporter(settings),
outDir)
- val bindings = new ScalaBindings
+ val bindings = Bindings()
val time = java.util.Calendar.getInstance.getTime
- bindings.put("msg", "Hello world", classOf[String])
- bindings.put("time", time, classOf[java.util.Date])
+ bindings.putValue("msg", "Hello world")
+ bindings.putValue("time", time)
val code = "package a { class Testi(vars: TestiVars) {import vars._;
print(msg + \": \" + time)}}"
val name = "a.Testi"
@@ -120,10 +121,10 @@
val srcDir = appDir.subdirectoryNamed("srcdir")
val interpreter = new ScalaInterpreter(settings, reporter(settings),
outDir)
- val bindings = new ScalaBindings
+ val bindings = Bindings()
val time = java.util.Calendar.getInstance.getTime
- bindings.put("msg", "Hello world", classOf[String])
- bindings.put("time", time, classOf[java.util.Date])
+ bindings.putValue("msg", "Hello world")
+ bindings.putValue("time", time)
val code = "package a { class Testi(vars: TestiVars) {import vars._;
print(msg + \": \" + time)}}"
val name = "a.Testi"
Modified:
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/html.scala
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/html.scala?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/html.scala
(original)
+++
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/html.scala
Thu Dec 24 09:09:54 2009
@@ -208,8 +208,11 @@
class html(vars: htmlVars) {
import java.util.Calendar
- import vars._
+ import javax.jcr.Node
import utils.RichJCR._
+ import vars._
+
+ val node: Node = currentNode
println {
<html>
@@ -218,13 +221,13 @@
</head>
<body>
<div id="Header">
- Welcome to the { currentNode("name") } forum
+ Welcome to the { node("name") } forum
— { Calendar.getInstance.getTime }
</div>
{ SearchBox.render(request) }
<div id="Content">
{ ThreadNewForm.render }
- { ThreadOverview.render(currentNode) }
+ { ThreadOverview.render(node) }
</div>
</body>
</html>
Modified:
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/search.scala
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/search.scala?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/search.scala
(original)
+++
sling/trunk/contrib/scripting/scala/samples/forum/src/main/resources/content/apps/forum/search.scala
Thu Dec 24 09:09:54 2009
@@ -37,6 +37,8 @@
<div id={ threadUUID + node.uuid + "content" }></div>
</p></li>
}
+
+ val node: Node = currentNode
println {
<html>
@@ -111,7 +113,7 @@
<div id="Content">
{
- val result = SearchBox.query(currentNode.session, request)
+ val result = SearchBox.query(node.session, request)
<h1>search results for query { request.getParameter("qt") }, hits: {
result.getSize() } </h1>
<ul>
{ result map searchDetail }
Modified:
sling/trunk/contrib/scripting/scala/samples/hello-world/src/main/resources/content/apps/helloworld/html.scala
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/scala/samples/hello-world/src/main/resources/content/apps/helloworld/html.scala?rev=893712&r1=893711&r2=893712&view=diff
==============================================================================
---
sling/trunk/contrib/scripting/scala/samples/hello-world/src/main/resources/content/apps/helloworld/html.scala
(original)
+++
sling/trunk/contrib/scripting/scala/samples/hello-world/src/main/resources/content/apps/helloworld/html.scala
Thu Dec 24 09:09:54 2009
@@ -51,11 +51,14 @@
import vars._
+ val node: Node = currentNode
+
println {
<html>
- <h1>{ "Hello " + currentNode("title") }</h1>
+ <h1>{ "Hello " + node("title") }</h1>
Today is { Calendar.getInstance.getTime } <br />
- My path is { currentNode.path }
+ My path is { node.path } <br />
+ : {
resource.adaptTo(classOf[javax.jcr.Node]).getProperty("title").getValue().getString()
} <br />
{ Tree(currentNode).render }
</html>
}