Skip to content

Commit

Permalink
Version 1.0.1: implement resource resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
larsga committed Jun 14, 2018
1 parent f9f08de commit 3852d96
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 19 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ To include JSLT in your project, depend on:
<dependency>
<groupId>com.schibsted.spt.data</groupId>
<artifactId>jslt</artifactId>
<version>0.1.0</version>
<version>0.1.1</version>
</dependency>
```

Expand Down Expand Up @@ -114,7 +114,6 @@ Unless required by applicable law or agreed to in writing, software distributed
## What is missing

Things to be done:
* Add API for pluggable import resolution.
* Move the tests out into JSON files.
* Write a proper spec with EBNF and everything.
* Fix the syntax ambiguity problem with `let` and `def`.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ ext {
}

group 'com.schibsted.spt.data'
version "0.1.0"
version "0.1.1"
project.description "A JSON query and transformation language"

check {
Expand Down
21 changes: 16 additions & 5 deletions src/main/java/com/schibsted/spt/data/jslt/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,40 +130,51 @@ public static Expression compile(String source,
private Collection<Function> functions;
private String source;
private Reader reader;
private ResourceResolver resolver;

private Parser(String source, Reader reader, Collection<Function> functions) {
private Parser(String source, Reader reader, Collection<Function> functions,
ResourceResolver resolver) {
this.functions = functions;
this.source = source;
this.reader = reader;
this.resolver = resolver;
}

/**
* Create a Parser reading JSLT source from the given Reader.
*/
public Parser(Reader reader) {
this("<unknown>", reader, Collections.EMPTY_SET);
this("<unknown>", reader, Collections.EMPTY_SET,
new ClasspathResourceResolver());
}

/**
* Create a new Parser with the given source name. The name is a string
* used in error messages.
*/
public Parser withSource(String thisSource) {
return new Parser(thisSource, reader, functions);
return new Parser(thisSource, reader, functions, resolver);
}

/**
* Create a new Parser with the given extension functions.
*/
public Parser withFunctions(Collection<Function> theseFunctions) {
return new Parser(source, reader, theseFunctions);
return new Parser(source, reader, theseFunctions, resolver);
}

/**
* Create a new Parser with the given resource resolver.
*/
public Parser withResourceResolver(ResourceResolver thisResolver) {
return new Parser(source, reader, functions, thisResolver);
}

/**
* Compile the JSLT from the defined parameters.
*/
public Expression compile() {
ParseContext ctx = new ParseContext(functions, source);
ParseContext ctx = new ParseContext(functions, source, resolver);
return ParserImpl.compileExpression(ctx, new JsltParser(reader));
}
}
32 changes: 32 additions & 0 deletions src/main/java/com/schibsted/spt/data/jslt/ResourceResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

// Copyright 2018 Schibsted Marketplaces Products & Technology As
//
// Licensed 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 com.schibsted.spt.data.jslt;

import java.io.Reader;

/**
* Given a string identifying a JSLT module file, return a Reader that
* produces the module. This interface can be used to look up module
* files other places than just on the classpath.
*/
public interface ResourceResolver {

/**
* Return a Reader for the given module.
*/
public Reader resolve(String jslt);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

// Copyright 2018 Schibsted Marketplaces Products & Technology As
//
// Licensed 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 com.schibsted.spt.data.jslt.impl;

import java.io.Reader;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import com.schibsted.spt.data.jslt.JsltException;
import com.schibsted.spt.data.jslt.ResourceResolver;

public class ClasspathResourceResolver implements ResourceResolver {

public Reader resolve(String jslt) {
try {
InputStream is = getClass().getClassLoader().getResourceAsStream(jslt);
if (is == null)
throw new JsltException("Cannot load resource '" + jslt + "': not found");
return new InputStreamReader(is, "utf-8");
} catch (IOException e) {
throw new JsltException("Couldn't load resource '" + jslt + "': " + e, e);
}
}
}
14 changes: 11 additions & 3 deletions src/main/java/com/schibsted/spt/data/jslt/impl/ParseContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import com.schibsted.spt.data.jslt.JsltException;
import com.schibsted.spt.data.jslt.Function;
import com.schibsted.spt.data.jslt.JsltException;
import com.schibsted.spt.data.jslt.ResourceResolver;

/**
* Class to encapsulate context information like available functions,
Expand All @@ -41,8 +42,10 @@ public class ParseContext {
private Map<String, Module> modules;
private Collection<FunctionExpression> funcalls; // delayed function resolution
private ParseContext parent;
private ResourceResolver resolver;

public ParseContext(Collection<Function> extensions, String source) {
public ParseContext(Collection<Function> extensions, String source,
ResourceResolver resolver) {
this.extensions = extensions;
this.functions = new HashMap();
for (Function func : extensions)
Expand All @@ -51,10 +54,11 @@ public ParseContext(Collection<Function> extensions, String source) {
this.source = source;
this.funcalls = new ArrayList();
this.modules = new HashMap();
this.resolver = resolver;
}

public ParseContext(String source) {
this(Collections.EMPTY_SET, source);
this(Collections.EMPTY_SET, source, new ClasspathResourceResolver());
}

public void setParent(ParseContext parent) {
Expand Down Expand Up @@ -127,4 +131,8 @@ public Function getImportedFunction(String prefix, String name, Location loc) {

return f;
}

public ResourceResolver getResolver() {
return resolver;
}
}
12 changes: 4 additions & 8 deletions src/main/java/com/schibsted/spt/data/jslt/parser/ParserImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,13 @@ public static Expression compileExpression(ParseContext ctx, JsltParser parser)

private static ExpressionImpl compileImport(Collection<Function> functions,
ParseContext parent,
String jstl) {
try (InputStream stream = ParserImpl.class.getClassLoader().getResourceAsStream(jstl)) {
if (stream == null)
throw new JsltException("Cannot load resource '" + jstl + "': not found");

Reader reader = new InputStreamReader(stream, "UTF-8");
ParseContext ctx = new ParseContext(functions, jstl);
String jslt) {
try (Reader reader = parent.getResolver().resolve(jslt)) {
ParseContext ctx = new ParseContext(functions, jslt, parent.getResolver());
ctx.setParent(parent);
return compileModule(ctx, new JsltParser(reader));
} catch (IOException e) {
throw new JsltException("Couldn't read resource " + jstl, e);
throw new JsltException("Couldn't read resource " + jslt, e);
}
}

Expand Down

0 comments on commit 3852d96

Please sign in to comment.