Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

# JosmTemplateParser

## Grammar

`{key}` - insert the _value_ of the tag that corresponds to _key_ .

`{%key}` - insert the _display value_ of the tag corresponding to _key_ if one is available, otherwise just insert the _value_ _(this is an extension)_ .

`?{condition1 'value1' | condition2 'value2' | 'value3'}` - use value1 if condition1 is satisfied, else use value2 if condition2 is satisfied, finally use value3 if no condition is satisfied. Condition can be either explicit - in JOSM search syntax - or implicit: The value is used when all tags referenced inside exist.

`!{search_expression 'template'}` - search_expression is evaluated and first matching primitive is used as context for template. Useful for example to get tags of parent relation.

`\` - use a backslash to escape special characters '{', '}', '?', '!'. E.g. What is this\? It is a `{type}\!`.

`{special:everything}` - prints all available values, output is implementation dependent.

`{special:id}` - prints the ID of the OSM element.

`{special:localName}` - prints the localized name, that is the value of _name:lang_ for your language if it is available, or the value of _name_ if it is not.


## Usage

Expand Down Expand Up @@ -35,6 +53,6 @@ You can either download the jar from github or add the following to your build.g

dependencies {
...
compile 'ch.poole.osm:JosmTemplateParser:0.2.0'
compile 'ch.poole.osm:JosmTemplateParser:0.3.0'
...
}
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ apply plugin: 'maven-publish'
apply plugin: 'signing'


version = '0.2.0'
version = '0.3.0'

java {
sourceCompatibility = JavaVersion.VERSION_1_8
Expand Down Expand Up @@ -143,8 +143,8 @@ repositories {

// In this section you declare the dependencies for your production and test code
dependencies {
implementation "ch.poole.osm:JosmFilterParser:0.9.0"
implementation "ch.poole.osm:JosmFilterParser:0.14.0"
compileOnly 'org.jetbrains:annotations:15.0'
testCompileOnly 'org.jetbrains:annotations:15.0'
testCompileOnly 'junit:junit:4.12'
testImplementation 'junit:junit:4.12'
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,21 @@ import java.util.Locale;
import java.util.Stack;

/**
{tag} - insert the value of the tag.
{key} - insert the value of the tag that corresponds to key.
{%key} - insert the display value of the tag corresponding to key if one is available, otherwise just insert the value (this is an extension) .
?{condition1 'value1' | condition2 'value2' | 'value3'} - use value1 if condition1 is satisfied, else use value2 if condition2 is satisfied, finally use value3 if no condition is satisfied. Condition can be either explicit - in JOSM search syntax - or implicit: The value is used when all tags referenced inside exist.
!{search_expression 'template'} - search_expression is evaluated and first matching primitive is used as context for template. Useful for example to get tags of parent relation.
\ - use a backslash to escape special characters '{', '}', '?', '!'. E.g. What is this\? It is a {type}\!.

{special:everything} prints all available values, available for formatting of both primitives and waypoints.
{special:id} prints the ID of the osm primitive.
{special:localName} prints the localized name, that is the value of name:lang for your language if it is available, or the value of name if it is not.
{special:everything} - prints all available values, output is implementation dependent.
{special:id} - prints the ID of the OSM element.
{special:localName} - prints the localized name, that is the value of name:lang for your language if it is available, or the value of name if it is not.
*/
public class JosmTemplateParser
{
Stack < Boolean > startParen = new Stack < Boolean > ();
private static final String USE_DISPLAY_VALUE = "%"; // extension

private Stack < Boolean > startParen = new Stack < Boolean > ();

public List < Formatter > formatters() throws JosmTemplateParseException
{
Expand Down Expand Up @@ -140,7 +143,7 @@ TOKEN :
< DEFAULT >
TOKEN :
{
< LITERAL : (~[ "\'", "\\", "?", "!", "|", "{", "}" ])+ >
< LITERAL : (~[ "\'", "\\", "?", "!", "|", "{", "}"])+ >
}

/**
Expand All @@ -154,7 +157,7 @@ String literal() :
t = < LITERAL >
{
return t.image;
}
}
}

/**
Expand Down Expand Up @@ -307,6 +310,7 @@ List < Formatter > template() :
String s = null;
Formatter f = null;
Token t = null;
Token u = null;
}
{
(
Expand Down Expand Up @@ -360,12 +364,16 @@ List < Formatter > template() :
LOOKAHEAD(< CURLY_START > literal() < CURLY_END >)
(
(
< CURLY_START >
< CURLY_START >
s = literal()
< CURLY_END >
)
{
result.add(new Tag(s));
if (s != null && s.startsWith(USE_DISPLAY_VALUE)) {
result.add(new Tag(s.substring(1), true));
} else {
result.add(new Tag(s, false));
}
}
)
)
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/ch/poole/osm/josmtemplateparser/Search.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.poole.osm.josmtemplateparser;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -36,7 +37,7 @@ public Search(@NotNull String searchExpression, @NotNull String template) throws
@NotNull
public String format(@NotNull Type type, @Nullable Meta meta, @Nullable Map<String, String> tags) {
if (meta != null) {
List<Object> matches = meta.getMatchingElements(condition);
List<Serializable> matches = meta.getMatchingElements(condition);
if (!matches.isEmpty()) {
Meta match = meta.wrap(matches.get(0));
return Util.listFormat(formatters, match.getType(), match, match.getTags());
Expand Down
28 changes: 22 additions & 6 deletions src/main/java/ch/poole/osm/josmtemplateparser/Tag.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,40 @@
*/
public class Tag implements Formatter {

private final String key;
private static final String USE_DISPLAY_VALUE_PREFIX = "%";

public Tag(@NotNull String key) {
private final String key;
private final boolean useDisplayValue;

public Tag(@NotNull String key, boolean useDisplayValue) {
this.key = key;
this.useDisplayValue = useDisplayValue;
}

@Override
@NotNull
public String format(@NotNull Type type, @Nullable Meta meta, @Nullable Map<String, String> tags) {
if (tags == null) {
return "";
}
String value = tags.get(key);
return value != null ? value : "";
return value != null ? displayValue(meta, key, value) : "";
}


/**
* Return a suitable value for display
*
* @param meta the Meta object or null
* @param key the key
* @param value the original value
* @return a value suitable for display
*/
private @NotNull String displayValue(@Nullable Meta meta, @NotNull String key, @NotNull String value) {
return meta != null && useDisplayValue ? meta.displayValue(key, value) : value;
}

@Override
public String toString() {
return "{" + key + "}";
return "{" + (useDisplayValue ? USE_DISPLAY_VALUE_PREFIX : "") + key + "}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -99,12 +100,12 @@ public Map<String, String> getTags() {
}

@Override
public List<Object> getMatchingElements(@NotNull Condition c) {
public List<Serializable> getMatchingElements(@NotNull Condition c) {
return Arrays.asList(this);
}

@Override
public @NotNull Meta wrap(Object o) {
public @NotNull Meta wrap(Serializable o) {
return this;
}
};
Expand Down Expand Up @@ -144,6 +145,9 @@ public Map<String, String> getTags() {
@Test
public void specialLocalNameTest() {
TestMeta meta = new TestMeta() {

private static final long serialVersionUID = 1L;

@Override
public Map<String, String> getTags() {
Map<String, String> tags = new HashMap<>();
Expand All @@ -157,6 +161,29 @@ public Map<String, String> getTags() {
assertEquals(1, f.size());
assertEquals("grrr2", f.get(0).format(Type.NODE, meta, null));
}

@Test
public void displayValueTest() {
Map<String, String> tags = new HashMap<>();
tags.put("te%st1", "grrr");
tags.put("name", "grrr2");
TestMeta meta = new TestMeta() {

private static final long serialVersionUID = 1L;

@Override
public Map<String, String> getTags() {
return tags;
}
};

List<Formatter> f = parse("{%name}");
assertEquals(1, f.size());
assertEquals("GRRR2", f.get(0).format(Type.NODE, meta, tags));
f = parse("{te%st1}");
assertEquals(1, f.size());
assertEquals("grrr", f.get(0).format(Type.NODE, meta, tags));
}

/**
* Parse a filter string and return the Condition object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ private void parseData(String inputFile, String resultsFile) {
} catch (FileNotFoundException fnfex) {
System.err.println("File not found " + fnfex.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AssertionError ae) {
System.err.println("Assertion failed for " + line);
Expand All @@ -158,15 +157,13 @@ private void parseData(String inputFile, String resultsFile) {
try {
inputRules.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (outputExpected != null) {
try {
outputExpected.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Expand Down
18 changes: 12 additions & 6 deletions src/test/java/ch/poole/osm/josmtemplateparser/TestMeta.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ch.poole.osm.josmtemplateparser;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
Expand All @@ -16,7 +17,7 @@
* @author simon
*
*/
public class TestMeta implements Meta {
public class TestMeta implements Meta, Serializable {

long id;
long version;
Expand Down Expand Up @@ -118,12 +119,12 @@ public boolean hasRole(@NotNull String role) {
}

@Override
public Object getPreset(@NotNull String presetPath) {
public Serializable getPreset(@NotNull String presetPath) {
return presetPath;
}

@Override
public boolean matchesPreset(@NotNull Object preset) {
public boolean matchesPreset(@NotNull Serializable preset) {
return preset.equals(this.preset);
}

Expand Down Expand Up @@ -153,17 +154,22 @@ public boolean isAllInDownloadedArea() {
}

@Override
public boolean isChild(@NotNull Type type, @NotNull Meta element, List<Object> parents) {
public boolean isChild(@NotNull Type type, @NotNull Meta element, List<Serializable> parents) {
return isChild;
}

@Override
public boolean isParent(@NotNull Type type, @NotNull Meta meta, @NotNull List<Object> children) {
public boolean isParent(@NotNull Type type, @NotNull Meta meta, @NotNull List<Serializable> children) {
return isParent;
}

@Override
public String displayValue(@NotNull String key, @NotNull String value) {
return value.toUpperCase();
}

@Override
public @NotNull Meta wrap(Object o) {
public @NotNull Meta wrap(Serializable o) {
return new TestMeta();
}
}
Loading