package de.axone.web.rest;
import java.io.IOException;
import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.axone.tools.Mapper;
import de.axone.tools.PasswordBuilder;
import de.axone.web.Tag;
public class RestFunctionDescription {
private String name;
private RestFunctionRoute route;
private String description;
private LinkedHashMap<String, Method> methods = new LinkedHashMap<String, Method>();
private String group;
private String template;
public RestFunctionDescription( String name, String description ) {
this.name = name;
this.description = description;
}
public Method addMethod( String name, String description ) {
Method method = new Method( name, description );
methods.put( name, method );
return method;
}
public RestFunctionDescription setTemplate( String group, String template ){
this.group = group;
this.template = template;
return this;
}
public void setRoute( RestFunctionRoute route ){
this.route = route;
}
public String getTemplateGroup(){
return group;
}
public String getTemplate(){
return template;
}
public String toHtml( boolean detailed ) {
StringBuilder result = new StringBuilder();
result.append( "<div class=\"function\">\n" );
result.append( "<h1>" ).append( name ).append( "</h1>\n" );
if( route != null )
result.append( "<div class=\"route\">" ).append( route.toString() ).append( "</div>" );
result.append( "<p>" ).append( description ).append( "</p>\n" );
if( methods.size() > 0 ) {
result.append( "<ul class=\"methods\">" );
for( Method method : methods.values() ) {
result.append( "<li>" ).append( method.toHtml() ).append(
"</li>\n" );
}
result.append( "</ul>" );
}
result.append( "</div>" );
return result.toString();
}
public static class Method {
private String name;
private String description;
private LinkedHashMap<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
private Parameter returnValue;
private List<Example> examples = new LinkedList<Example>();
private String html;
public Method( String name, String description ) {
this.name = name;
this.description = description;
}
public Method addParameter( Parameter parameter ){
parameters.put( parameter.name, parameter );
return this;
}
public Method addParameter( String name, String description ){
parameters.put( name, new Parameter( name, description ) );
return this;
}
public Method addParameter( String name, String description, String defaultValue ) {
parameters.put( name, new Parameter( name, description, defaultValue ) );
return this;
}
public Method setReturnValue( String name, String description ) {
returnValue = new Parameter( name, description );
return this;
}
public Method addExample( Example example ) {
this.examples.add( example );
return this;
}
public Method addExample( Example example, String explain ) {
example.setExplain( explain );
return addExample( example );
}
public Method setHtml( String html ){
this.html = html;
return this;
}
public String toHtml() {
StringBuilder result = new StringBuilder();
result
.append( "<div class=\"method\">\n" )
.append( "<h2>" ).append( name ).append( "</h2>\n" )
.append( "<p>" ).append( description ).append( "</p>\n" )
;
if( parameters.size() > 0 ) {
result.append( "<ul class=\"parameters\">" );
for( Parameter parameter : parameters.values() ) {
result
.append( "<li>" )
.append( parameter.toHtml() )
.append( "</li>\n" );
}
result.append( "</ul>\n" );
}
if( returnValue != null ) {
result
.append( "<p>Returns: " )
.append( returnValue.toHtml() )
.append( "</p>\n" );
}
if( examples.size() > 0 ){
for( Example example : examples ){
result.append( "<p class=\"example\">Example:" );
example.toHtml( result );
result.append( "</p>\n" );
}
}
if( html != null ){
result.append( html );
}
result.append( "</div>" );
return result.toString();
}
}
public static class Parameter {
private String name;
private String description;
private String defaultValue;
public Parameter( String name, String description ) {
this( name, description, null );
}
public Parameter( String name, String description, String defaultValue ) {
this.name = name;
this.description = description;
this.defaultValue = defaultValue;
}
public StringBuilder toHtml() {
StringBuilder result = new StringBuilder();
result
.append( "<span class=\"parameter\">" )
.append( " <em class=\"name\">" ).append( name ).append( "</em>" )
.append( " <span class=\"description\">" ).append( description ).append( "</span>" )
;
if( defaultValue != null ) {
result.append( " <tt class=\"defaultValue\">" ).append( name ).append( "</tt>" );
}
result.append( "</span>" );
return result;
}
}
public interface Example {
public abstract StringBuilder toHtml( StringBuilder result );
public void setExplain( String explain );
public String explain();
}
public abstract static class AbstractExample implements Example {
protected final String method;
protected final String path;
protected String explain;
public AbstractExample( String method, String path ){
this( method, path, null );
}
public AbstractExample( String method, String path, String explain ){
this.method = method;
this.path = path;
this.explain = explain;
}
@Override
public void setExplain( String explain ){
this.explain = explain;
}
@Override
public String explain(){
return explain;
}
@Override
public StringBuilder toHtml( StringBuilder result ){
return result;
}
}
public static class GetExample extends AbstractExample {
public GetExample( String path ){
super( "GET", path );
}
@Override
public StringBuilder toHtml( StringBuilder result ) {
Tag.simpleBB( result, "a", path, "href", path );
return super.toHtml( result );
}
}
public static class FormExample extends AbstractExample {
protected Map<String,String> arguments;
private final String id;
public FormExample( String method, String path, Map<String,String> arguments ){
super( method, path );
this.arguments = arguments;
this.id = PasswordBuilder.makeSimplaPasswd();
}
public FormExample( String method, String path, String ... arguments ){
this( method, path, Mapper.treeMap( arguments ) );
}
@Override
public StringBuilder toHtml( StringBuilder result ) {
StringBuilder content = new StringBuilder();
for( String name : arguments.keySet() ){
String idStr = id + "_" + name;
Tag.simpleBB( content, "label", name,
"for", idStr );
Tag.simpleBB( content, "input", null,
"id", idStr, "name", name, "value", arguments.get( name ) );
}
Tag.simpleBB( content, "input", null,
"type", "hidden", "name", "action", "value", method );
Tag.simpleBB( content, "input", null, "type", "submit" );
Tag.simpleBB( result, "form", content.toString(), false,
"name", id, "action", path, "method", "POST" );
return super.toHtml( result );
}
}
public static class JsonExample extends AbstractExample {
protected Object json;
public JsonExample( String method, String path, Object json ){
super( method, path );
this.json = json;
}
@Override
public StringBuilder toHtml( StringBuilder result ) {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion( JsonInclude.Include.NON_NULL );
String data;
try( StringWriter s = new StringWriter() ){
mapper.writeValue( s, json );
data = s.toString();
} catch( IOException e ) {
throw new IllegalArgumentException( "Cannot encode Json" );
};
StringBuilder content = new StringBuilder();
Tag.simpleBB( content, "input", null, "name", "data", "value", data );
Tag.simpleBB( content, "input", null, "type", "submit" );
Tag.simpleBB( result, "form", content.toString(), false,
"class", "jsonForm", "action", path, "method", method );
return super.toHtml( result );
}
}
}