Skip to content

Commit 6c2663d

Browse files
committed
Merge pull request #161 from sparkprime/java_comparison
Java comparison
2 parents 56a91d4 + 1f61ac3 commit 6c2663d

10 files changed

+396
-0
lines changed
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.class
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
Copyright 2016 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import java.util.Arrays;
18+
import java.util.HashSet;
19+
import java.util.Set;
20+
21+
public class BaseTemplate extends JsonnetObject {
22+
public Set<String> nonHiddenFields() {
23+
Set<String> r = super.nonHiddenFields();
24+
r.addAll(Arrays.asList("apiVersion", "kind", "spec"));
25+
return r;
26+
}
27+
28+
// Mandatory param
29+
public Object accessToken() {
30+
throw new RuntimeException("accessToken must be defined");
31+
}
32+
33+
// Optional params
34+
public Object image() { return "gcr.io/cooltool-1009/pipeline_image:latest"; }
35+
public Object[] extraEnv() { return new Object[]{}; }
36+
37+
public Object apiVersion() { return "v1"; }
38+
public Object kind() { return "ReplicationController"; }
39+
40+
public class BaseTemplateSpec extends JsonnetObject {
41+
public Set<String> nonHiddenFields() {
42+
Set<String> r = super.nonHiddenFields();
43+
r.addAll(Arrays.asList("replicas", "spec"));
44+
return r;
45+
}
46+
47+
public Object replicas() { return 1.0; }
48+
49+
public class BaseTemplateSpecSpec extends JsonnetObject {
50+
public Set<String> nonHiddenFields() {
51+
Set<String> r = super.nonHiddenFields();
52+
r.addAll(Arrays.asList("containers"));
53+
return r;
54+
}
55+
56+
public class Container0 extends JsonnetObject {
57+
public Set<String> nonHiddenFields() {
58+
Set<String> r = super.nonHiddenFields();
59+
r.addAll(Arrays.asList("env", "image", "name"));
60+
return r;
61+
}
62+
63+
class Env0 extends JsonnetObject {
64+
public Set<String> nonHiddenFields() {
65+
Set<String> r = super.nonHiddenFields();
66+
r.addAll(Arrays.asList("name", "value"));
67+
return r;
68+
}
69+
public Object name() { return "ACCESSTOKEN"; }
70+
public Object value() { return BaseTemplate.this.accessToken(); }
71+
}
72+
73+
public Object[] env() {
74+
// Concatenating arrays (first + second) is hard in Java.
75+
Object[] first = new Object[]{ new Env0() };
76+
Object[] second = BaseTemplate.this.extraEnv();
77+
Object[] result = Arrays.copyOf(first, first.length + second.length);
78+
System.arraycopy(second, 0, result, first.length, second.length);
79+
return result;
80+
}
81+
public Object image() { return BaseTemplate.this.image(); }
82+
public Object name() { return "twitter-to-redis"; }
83+
}
84+
85+
public Object containers() { return new Object[] { new Container0() }; }
86+
}
87+
public Object spec() { return new BaseTemplateSpecSpec(); }
88+
89+
}
90+
public Object spec() { return new BaseTemplateSpec(); }
91+
}
92+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Copyright 2016 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import java.util.HashSet;
18+
import java.util.Set;
19+
20+
public class JsonnetObject {
21+
public Set<String> nonHiddenFields() { return new HashSet<String>(){}; }
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
Copyright 2016 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import java.lang.reflect.Method;
18+
import java.lang.reflect.InvocationTargetException;
19+
import java.util.HashSet;
20+
import java.util.Set;
21+
22+
public class JsonnetValue {
23+
public static String manifest(Object value) {
24+
StringBuffer buf = new StringBuffer();
25+
if (value == null) {
26+
// FIXME: does not escape the string
27+
buf.append("null");
28+
29+
} else if (value instanceof String) {
30+
// FIXME: does not escape the string
31+
buf.append("\"" + value + "\"");
32+
33+
} else if (value instanceof Double) {
34+
buf.append(value.toString());
35+
36+
} else if (value instanceof Boolean) {
37+
buf.append(value.toString());
38+
39+
} else if (value instanceof Object[]) {
40+
Object[] arr = (Object[]) value;
41+
buf.append("[");
42+
String prefix = " ";
43+
for (Object element : arr) {
44+
buf.append(prefix);
45+
prefix = ", ";
46+
buf.append(manifest(element));
47+
}
48+
buf.append(" ]");
49+
50+
} else if (value instanceof JsonnetObject) {
51+
JsonnetObject obj = (JsonnetObject) value;
52+
buf.append("{");
53+
String prefix = " ";
54+
for (String field : obj.nonHiddenFields()) {
55+
buf.append(prefix);
56+
prefix = ", ";
57+
buf.append("\"" + field + "\": ");
58+
try {
59+
Method method = obj.getClass().getMethod(field);
60+
Object fieldValue = method.invoke(obj);
61+
buf.append(manifest(fieldValue));
62+
} catch (IllegalArgumentException e) {
63+
System.out.println(e);
64+
} catch (IllegalAccessException e) {
65+
System.out.println(e);
66+
} catch (InvocationTargetException e) {
67+
System.out.println(e);
68+
} catch (SecurityException e) {
69+
System.out.println(e);
70+
} catch (NoSuchMethodException e) {
71+
System.out.println(e);
72+
}
73+
}
74+
buf.append(" }");
75+
} else {
76+
throw new RuntimeException("Got weird type: " + value.getClass());
77+
}
78+
return buf.toString();
79+
}
80+
}
81+
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Jsonnet to Java
2+
---------------
3+
4+
This little code example shows how a Jsonnet config using object-oriented features can be
5+
transliterated (in a structure-preserving manner) to use the object-oriented features of Java. Not
6+
all Jsonnet programs can be converted to Java because Jsonnet has mixins and virtual inner classes.
7+
The semantics are also different, as Jsonnet is lazy and Java is eager. Likewise, Java programs
8+
cannot all be converted to Jsonnet because they have mutable state and I/O.
9+
10+
However said all this, there is a significant overlap between the two languages. This example fits
11+
within that overlap.
12+
13+
14+
Execute Jsonnet code
15+
--------------------
16+
17+
```
18+
jsonnet sub-template.jsonnet
19+
```
20+
21+
22+
Execute Java code
23+
-----------------
24+
25+
We pipe into jsonnet - to pretty-print the output JSON.
26+
27+
```
28+
javac *.java && java Test | jsonnet -
29+
```
30+
31+
32+
Structure of Java code
33+
----------------------
34+
35+
The translation is as as follows:
36+
37+
* Everything is typed as Object, as Jsonnet is dynamically typed.
38+
* Jsonnet arrays are Object[], and primitives are Boolean / Double / String.
39+
* Jsonnet objects because singleton instances of Java classes that extend JsonnetObject.
40+
* Jsonnet fields become Java methods with no parameters (fields are virtual in Jsonnet).
41+
* Jsonnet hidden field status is represented with a method nonHiddenFields which returns a set of
42+
field names. Other fields are considered hidden.
43+
* There are 2 liberties taken -- output strings are not escaped properly, and the JSON is printed on
44+
a single line instead of pretty-printed with indenting.
45+
46+
The Java code has a number of auxiliary framework functions to provide Jsonnet functionality that is
47+
implicit in the Jsonnet language.
48+
49+
* The Test class chooses an object and manifests it to stdout.
50+
* The JsonnetValue class implements manifestation, as a visitor over possible JSON values that
51+
builds JSON strings. For objects, it iterates over the non-hidden fields and manifests each value
52+
by reflectively calling that function.
53+
54+
55+
Reference JSON
56+
--------------
57+
58+
For reference, the JSON that should be output is given in sub-template.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright 2016 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
public class SubTemplate extends BaseTemplate {
18+
// Supply my access token and pinned version.
19+
public String accessToken() {
20+
return "xxxxx";
21+
}
22+
public String image() {
23+
return "gcr.io/cooltool-1009/pipeline_image@sha256:....";
24+
}
25+
public class SubTemplateSpec extends BaseTemplate.BaseTemplateSpec {
26+
public Object replicas() { return 2.0; }
27+
}
28+
public Object spec() {
29+
return new SubTemplateSpec();
30+
}
31+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
Copyright 2016 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
public class Test {
18+
public static void main(String[] args) {
19+
System.out.println(JsonnetValue.manifest(new SubTemplate()));
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
Copyright 2016 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
{
18+
// Mandatory param
19+
accessToken:: error "accessToken must be defined",
20+
21+
// Optional params
22+
image:: "gcr.io/cooltool-1009/pipeline_image:latest",
23+
extraEnv:: [],
24+
25+
apiVersion: "v1",
26+
kind: "ReplicationController",
27+
spec: {
28+
replicas: 1,
29+
spec: {
30+
containers: [
31+
{
32+
env: [
33+
{
34+
name: "ACCESSTOKEN",
35+
value: $.accessToken,
36+
},
37+
] + $.extraEnv,
38+
image: $.image,
39+
name: "twitter-to-redis",
40+
},
41+
],
42+
},
43+
},
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"apiVersion": "v1",
3+
"kind": "ReplicationController",
4+
"spec": {
5+
"replicas": 2,
6+
"spec": {
7+
"containers": [
8+
{
9+
"env": [
10+
{
11+
"name": "ACCESSTOKEN",
12+
"value": "xxxxx"
13+
}
14+
],
15+
"image": "gcr.io/cooltool-1009/pipeline_image@sha256:....",
16+
"name": "twitter-to-redis"
17+
}
18+
]
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)