Refactoring and updating of Views.
This commit is contained in:
parent
2e454c6f60
commit
7e2e176e6a
@ -1,34 +0,0 @@
|
||||
package groowt.view;
|
||||
|
||||
import groovy.lang.Closure;
|
||||
import groovy.lang.GroovyObjectSupport;
|
||||
import groovy.lang.MetaProperty;
|
||||
import groovy.lang.Writable;
|
||||
import org.codehaus.groovy.runtime.typehandling.GroovyCastException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* TODO: create a Map implementation that can access the View for keys/values, or do a metaclass thing
|
||||
* TODO: get rid of this and just move the asType stuff to GStringTemplateView
|
||||
*/
|
||||
public abstract class AbstractView extends GroovyObjectSupport implements View {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T asType(Class<T> clazz) {
|
||||
if (clazz.isAssignableFrom(this.getClass())) {
|
||||
return (T) this;
|
||||
} else if (clazz.equals(Writable.class)) {
|
||||
return (T) this.asWritable();
|
||||
} else if (clazz.equals(Closure.class)) {
|
||||
return (T) this.asClosure();
|
||||
} else if (clazz.equals(Map.class)) {
|
||||
return (T) this.getMetaClass().getProperties().stream()
|
||||
.collect(Collectors.toMap(MetaProperty::getName, metaProperty -> metaProperty.getProperty(this)));
|
||||
} else {
|
||||
throw new GroovyCastException(this, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,7 @@ import java.util.Map;
|
||||
/**
|
||||
* Delegates to self.
|
||||
*/
|
||||
public class GStringTemplateView extends AbstractView {
|
||||
public class GStringTemplateView implements View {
|
||||
|
||||
private final GStringTemplateEngine engine;
|
||||
private final Object src;
|
||||
|
@ -7,7 +7,7 @@ import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
|
||||
public class GroovyTemplateView extends AbstractView {
|
||||
public class GroovyTemplateView implements View {
|
||||
|
||||
private final Template template;
|
||||
|
||||
|
@ -2,6 +2,7 @@ package groowt.view;
|
||||
|
||||
import groovy.lang.Closure;
|
||||
import groovy.lang.Writable;
|
||||
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
@ -10,28 +11,6 @@ import java.io.Writer;
|
||||
@FunctionalInterface
|
||||
public interface View {
|
||||
|
||||
/**
|
||||
* TODO: consider making this a (package private?) separate class, perhaps with support for GStringTemplateViews, etc.?
|
||||
*/
|
||||
final class ClosureView extends Closure<Object> {
|
||||
|
||||
private final View view;
|
||||
|
||||
public ClosureView(View view) {
|
||||
super(view, view);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public void doCall(Writer writer) throws IOException {
|
||||
this.view.renderTo(writer);
|
||||
}
|
||||
|
||||
public String doCall() {
|
||||
return this.view.render();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void renderTo(Writer writer) throws IOException;
|
||||
|
||||
default String render() {
|
||||
@ -44,15 +23,37 @@ public interface View {
|
||||
}
|
||||
}
|
||||
|
||||
default Writable asWritable() {
|
||||
return writer -> {
|
||||
this.renderTo(writer);
|
||||
return writer;
|
||||
};
|
||||
@SuppressWarnings("rawtypes")
|
||||
default Closure asWritable() {
|
||||
if (this instanceof Closure) {
|
||||
return (Closure) this;
|
||||
} else {
|
||||
return new WritableClosureView(this);
|
||||
}
|
||||
}
|
||||
|
||||
default Closure<Object> asClosure() {
|
||||
return new ClosureView(this);
|
||||
@SuppressWarnings("rawtypes")
|
||||
default Closure asClosure() {
|
||||
if (this instanceof Closure) {
|
||||
return (Closure) this;
|
||||
} else {
|
||||
return new WritableClosureView(this);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default <T> T asType(Class<T> clazz) {
|
||||
if (clazz.isInstance(this)) {
|
||||
return clazz.cast(this);
|
||||
} else if (clazz.equals(Writable.class)) {
|
||||
return (T) this.asWritable();
|
||||
} else if (clazz.equals(Closure.class)) {
|
||||
return (T) this.asClosure();
|
||||
} else if (clazz.equals(String.class)) {
|
||||
return (T) this.render();
|
||||
} else {
|
||||
return DefaultGroovyMethods.asType(this, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
37
views/src/main/java/groowt/view/WritableClosureView.java
Normal file
37
views/src/main/java/groowt/view/WritableClosureView.java
Normal file
@ -0,0 +1,37 @@
|
||||
package groowt.view;
|
||||
|
||||
import groovy.lang.Closure;
|
||||
import groovy.lang.Writable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
final class WritableClosureView extends Closure<Object> implements View, Writable {
|
||||
|
||||
private final View view;
|
||||
|
||||
public WritableClosureView(View view) {
|
||||
super(view, view);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTo(Writer writer) throws IOException {
|
||||
this.view.renderTo(writer);
|
||||
}
|
||||
|
||||
public void doCall(Writer writer) throws IOException {
|
||||
this.view.renderTo(writer);
|
||||
}
|
||||
|
||||
public String doCall() {
|
||||
return this.view.render();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Writer writeTo(Writer out) throws IOException {
|
||||
this.view.renderTo(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
@ -14,8 +14,6 @@ public class GStringTemplateViewTests {
|
||||
|
||||
private static final class GreetingView extends GStringTemplateView {
|
||||
|
||||
private final String greeting = "Hello, world!";
|
||||
|
||||
public GreetingView(GStringTemplateEngine engine) {
|
||||
super(Map.of(
|
||||
"engine", engine,
|
||||
@ -24,7 +22,7 @@ public class GStringTemplateViewTests {
|
||||
}
|
||||
|
||||
public String getGreeting() {
|
||||
return this.greeting;
|
||||
return "Hello, world!";
|
||||
}
|
||||
|
||||
}
|
||||
@ -58,19 +56,10 @@ public class GStringTemplateViewTests {
|
||||
final var view = new GreetingView(this.engine);
|
||||
final var writable = view.asWritable();
|
||||
final var w = new StringWriter();
|
||||
writable.writeTo(w);
|
||||
writable.call(w);
|
||||
assertEquals("Hello, world!", w.toString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void coerceToMap() {
|
||||
final var view = new GreetingView(this.engine);
|
||||
final Map<String, Object> map = view.asType(Map.class);
|
||||
assertTrue(map.containsKey("greeting"));
|
||||
assertEquals("Hello, world!", map.get("greeting"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void yieldingViewSimple() {
|
||||
final var greetingView = new GreetingView(this.engine);
|
||||
|
Loading…
Reference in New Issue
Block a user