use of com.disney.groovity.model.ModelJsonWriter in project groovity by disney.
the class TestGroovityTags method testDocs.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testDocs() throws Exception {
Map map = null;
List<Map> docs = groovity.getLibraryDocs();
for (Map doc : docs) {
if (doc.get("path").equals("/doc.grvt")) {
map = doc;
break;
}
}
CharArrayWriter caw = new CharArrayWriter();
new ModelJsonWriter(caw).visit(map);
String output = caw.toString();
// System.out.println("DOCS TEST "+output);
Assert.assertEquals("{\"name\":\"doc\",\"path\":\"\\/doc.grvt\",\"functions\":[{\"name\":\"getFullName\",\"info\":\"Construct a full name\",\"args\":[{\"name\":\"first\",\"info\":\"first or given name\",\"nullable\":false,\"type\":\"String\"},{\"name\":\"middleName\",\"info\":\"\",\"nullable\":true,\"type\":\"String\"},{\"name\":\"lastName\",\"info\":\"last or family name\",\"nullable\":false,\"type\":\"String\"}],\"returns\":\"String\"}," + "{\"name\":\"getSmaller\",\"info\":\"Decide which number is smaller\",\"args\":[{\"name\":\"first\",\"info\":\"\",\"nullable\":false,\"type\":\"Number\"},{\"name\":\"second\",\"info\":\"\",\"nullable\":false,\"type\":\"Number\"}],\"returns\":\"Number\"}]}", output);
}
use of com.disney.groovity.model.ModelJsonWriter in project groovity by disney.
the class Http method tag.
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object tag(Map attributes, Closure body) throws Exception {
Object url = resolve(attributes, "url");
if (url == null) {
throw new RuntimeException("<g:http> requires 'url' attribute");
}
Object var = resolve(attributes, VAR);
String method = "GET";
Object methodAtt = resolve(attributes, "method");
if (methodAtt != null) {
method = methodAtt.toString();
}
boolean followRedirects = true;
Object redirectsAtt = resolve(attributes, "redirects");
if (redirectsAtt != null) {
followRedirects = Boolean.parseBoolean(redirectsAtt.toString());
}
CookieOption cookieOption = CookieOption.DEFAULT;
Object cookiesAtt = resolve(attributes, "cookies");
if (cookiesAtt != null) {
cookieOption = CookieOption.valueOf(cookiesAtt.toString().toUpperCase());
}
Object timeout = resolve(attributes, TIMEOUT);
final int timeoutSeconds = timeout == null ? -1 : timeout instanceof Number ? ((Number) timeout).intValue() : Integer.parseInt(timeout.toString());
Object target = resolve(attributes, "to");
if (target instanceof Class) {
if (!Object.class.equals(target)) {
target = ((Class) target).newInstance();
}
}
if (target == null) {
target = Object.class;
}
Object async = resolve(attributes, "async");
if (async != null && !(async instanceof Boolean)) {
async = Boolean.valueOf(async.toString());
}
HttpEntity dataEntity = null;
Object data = resolve(attributes, "data");
HttpClientContext clientContext = resolve(attributes, "context", HttpClientContext.class);
if (clientContext == null) {
clientContext = HttpClientContext.create();
}
if (clientContext.getCookieStore() == null) {
// we don't want to let cookies be shared across contexts
clientContext.setCookieStore(new BasicCookieStore());
}
if (clientContext.getAuthCache() == null) {
// we also don't want to share credentials across contexts
clientContext.setAuthCache(new BasicAuthCache());
}
final HttpClientContext fContext = clientContext;
ScriptHelper context = getScriptHelper(body);
Object oldOut = get(context, OUT);
// execute body to assemble URL params, headers, post body
Map variables = context.getBinding().getVariables();
URI uri;
URIBuilder builder;
ArrayList<Header> headers;
Optional<UserPass> userPass;
Optional<HttpSignatureSigner> signer;
Optional<HttpRequestInterceptor> interceptor;
try {
builder = new URIBuilder(url.toString());
bind(context, Uri.CURRENT_URI_BUILDER, builder);
headers = new ArrayList<Header>();
bind(context, com.disney.groovity.tags.Header.CURRENT_LIST_FOR_HEADERS, headers);
Credentials.acceptCredentials(variables);
Signature.acceptSigner(variables);
acceptInterceptor(variables);
StringWriter sw = new StringWriter();
bind(context, OUT, sw);
try {
Object rval = body.call();
if (rval instanceof Writable) {
((Writable) rval).writeTo(sw);
}
} finally {
bind(context, OUT, oldOut);
userPass = Credentials.resolveCredentials(variables);
signer = Signature.resolveSigner(variables);
interceptor = resolveInterceptor(variables);
}
String val = sw.toString();
if (val.trim().length() > 0) {
dataEntity = new StringEntity(val);
}
uri = builder.build();
if (userPass.isPresent()) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(userPass.get().getUser(), new String(userPass.get().getPass())));
clientContext.setCredentialsProvider(credsProvider);
}
} catch (URISyntaxException e1) {
throw new RuntimeException("Invalid URI " + url, e1);
} finally {
unbind(context, Uri.CURRENT_URI_BUILDER);
unbind(context, com.disney.groovity.tags.Header.CURRENT_LIST_FOR_HEADERS);
}
final HttpRequestBase request = "POST".equalsIgnoreCase(method) ? new HttpPost(uri) : "PUT".equalsIgnoreCase(method) ? new HttpPut(uri) : "HEAD".equalsIgnoreCase(method) ? new HttpHead(uri) : "DELETE".equalsIgnoreCase(method) ? new HttpDelete(uri) : "OPTIONS".equalsIgnoreCase(method) ? new HttpOptions(uri) : new HttpGet(uri);
if (headers.size() > 0) {
request.setHeaders(headers.toArray(new Header[0]));
}
if (request instanceof HttpEntityEnclosingRequest) {
if (data != null) {
// decide on strategy to convert data to entity
if (data instanceof HttpEntity) {
dataEntity = (HttpEntity) data;
} else {
// look at content type for a hint
Header targetType = request.getFirstHeader("Content-Type");
if (targetType != null && targetType.getValue().contains("json")) {
CharArrayWriter caw = new CharArrayWriter();
new ModelJsonWriter(caw).visit(data);
dataEntity = new StringEntity(caw.toString());
} else if (targetType != null && targetType.getValue().contains("xml")) {
if (data instanceof groovy.util.Node) {
dataEntity = new StringEntity(XmlUtil.serialize((groovy.util.Node) data));
} else if (data instanceof GPathResult) {
dataEntity = new StringEntity(XmlUtil.serialize((GPathResult) data));
} else if (data instanceof Element) {
dataEntity = new StringEntity(XmlUtil.serialize((Element) data));
} else if (data instanceof Document) {
dataEntity = new StringEntity(XmlUtil.serialize(((Document) data).getDocumentElement()));
} else {
// if it's not an XML model assume it's a well formed XML string
dataEntity = new StringEntity(data.toString());
}
} else if ((targetType != null && targetType.getValue().contains("x-www-form-urlencoded")) || (targetType == null && (data instanceof Map || data instanceof List))) {
// key/value pairs, accept a map, a list of maps, or a list of NameValuePairs
Iterator source = data instanceof Map ? ((Map) data).entrySet().iterator() : ((List) data).iterator();
ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
while (source.hasNext()) {
Object next = source.next();
if (next instanceof Map.Entry) {
Map.Entry entry = (Entry) next;
pairs.add(new BasicNameValuePair(entry.getKey().toString(), entry.getValue() != null ? entry.getValue().toString() : ""));
} else if (next instanceof NameValuePair) {
pairs.add((NameValuePair) next);
} else if (next instanceof Map) {
Iterator<Map.Entry> sub = ((Map) next).entrySet().iterator();
while (sub.hasNext()) {
Map.Entry se = sub.next();
pairs.add(new BasicNameValuePair(se.getKey().toString(), se.getValue() != null ? se.getValue().toString() : ""));
}
}
}
dataEntity = new UrlEncodedFormEntity(pairs);
} else if (targetType != null && targetType.getValue().contains("multipart/form-data")) {
// list of maps, each map must contain "name" and "body", plus optional "type" and "filename"
Iterator<Map> parts = ((List<Map>) data).iterator();
MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
while (parts.hasNext()) {
Map part = parts.next();
Object pbody = part.get("body");
String name = (String) part.get("name");
String type = (String) part.get("type");
String filename = (String) part.get("filename");
ContentType ct = type != null ? ContentType.parse(type) : null;
if (pbody instanceof File) {
if (ct == null) {
ct = ContentType.DEFAULT_BINARY;
}
meBuilder.addBinaryBody(name, (File) pbody, ct, filename);
} else if (pbody instanceof byte[]) {
if (ct == null) {
ct = ContentType.DEFAULT_BINARY;
}
meBuilder.addBinaryBody(name, (byte[]) pbody, ct, filename);
} else if (pbody instanceof ContentBody) {
meBuilder.addPart(name, (ContentBody) pbody);
} else if (pbody instanceof InputStream) {
if (ct == null) {
ct = ContentType.DEFAULT_BINARY;
}
meBuilder.addBinaryBody(name, (InputStream) pbody, ct, filename);
} else {
if (ct == null) {
ct = ContentType.DEFAULT_TEXT;
}
meBuilder.addTextBody(name, pbody.toString(), ct);
}
}
dataEntity = meBuilder.build();
} else {
// no help from content type header, check for modeled XML
if (data instanceof groovy.util.Node) {
dataEntity = new StringEntity(XmlUtil.serialize((groovy.util.Node) data), ContentType.APPLICATION_XML);
} else if (data instanceof GPathResult) {
dataEntity = new StringEntity(XmlUtil.serialize((GPathResult) data), ContentType.APPLICATION_XML);
} else if (data instanceof Element) {
dataEntity = new StringEntity(XmlUtil.serialize((Element) data), ContentType.APPLICATION_XML);
} else if (data instanceof Document) {
dataEntity = new StringEntity(XmlUtil.serialize(((Document) data).getDocumentElement()), ContentType.APPLICATION_XML);
} else if (data instanceof byte[]) {
dataEntity = new ByteArrayEntity((byte[]) data);
} else if (data instanceof InputStream) {
dataEntity = new InputStreamEntity((InputStream) data);
} else if (data instanceof File) {
dataEntity = new FileEntity((File) data);
} else {
// best option left is to post the toString value of the data
dataEntity = new StringEntity(data.toString());
}
}
}
}
if (dataEntity != null) {
((HttpEntityEnclosingRequest) request).setEntity(dataEntity);
}
}
RequestConfig.Builder configBuilder = request.getConfig() == null ? RequestConfig.custom() : RequestConfig.copy(request.getConfig());
if (!followRedirects) {
configBuilder.setRedirectsEnabled(followRedirects);
}
configBuilder.setCookieSpec(cookieOption.getCookieSpec());
request.setConfig(configBuilder.build());
final String varName = var != null ? var.toString() : null;
ResponseHandler handler = null;
try {
Function handlerFunction = (Function) get(body, Handler.HANDLER_BINDING);
if (handlerFunction != null) {
handler = new ResponseHandler<Object>() {
@Override
public Object handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
return handlerFunction.apply(response);
}
};
}
unbind(body, Handler.HANDLER_BINDING);
} catch (Exception e) {
}
if (handler == null) {
handler = new AutoParsingResponseHandler(target);
}
final List<HttpRequestInterceptor> interceptors = new ArrayList<>();
if (signer.isPresent()) {
interceptors.add(signer.get());
}
if (interceptor.isPresent()) {
interceptors.add(interceptor.get());
}
final ResponseHandler rHandler = handler;
final boolean isAsync = (async != null && Boolean.TRUE.equals(async));
Callable<Object> requester = new Callable() {
public Object call() throws Exception {
TimeoutTask timeoutTask = null;
if (timeoutSeconds > 0) {
timeoutTask = new TimeoutTask(request);
timeoutTimer.schedule(timeoutTask, timeoutSeconds * 1000);
}
try {
Binding oldThreadBinding = null;
if (isAsync) {
oldThreadBinding = ScriptHelper.THREAD_BINDING.get();
Binding asyncBinding = new Binding();
asyncBinding.setVariable("request", request);
ScriptHelper.THREAD_BINDING.set(asyncBinding);
}
try {
for (HttpRequestInterceptor interceptor : interceptors) {
interceptor.process(request, null);
}
return httpClient.execute(request, rHandler, fContext);
} finally {
if (isAsync) {
if (oldThreadBinding == null) {
ScriptHelper.THREAD_BINDING.remove();
} else {
ScriptHelper.THREAD_BINDING.set(oldThreadBinding);
}
}
}
} catch (HttpResponseException e) {
if (isAsync) {
log.error("Async HTTP response error for " + request.getURI() + ": " + e.getMessage());
}
throw e;
} catch (Exception e) {
if (request.isAborted()) {
if (isAsync) {
log.error("Async <g:http> request timed out for " + request.getURI());
}
throw new TimeoutException("Timed out executing <g:http> for " + request.getURI());
} else {
if (isAsync) {
log.error("Async <g:http> request error for " + request.getURI(), e);
}
throw new RuntimeException("Error executing <g:http> for " + request.getURI(), e);
}
} finally {
if (timeoutTask != null) {
timeoutTask.cancel();
}
}
}
};
Object responseVar = null;
if (isAsync) {
// return the Future to the calling code
Future<Object> f = asyncExecutor.submit(requester);
responseVar = new Future<Object>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return f.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
return f.isCancelled();
}
@Override
public boolean isDone() {
return f.isDone();
}
@Override
public Object get() throws InterruptedException, ExecutionException {
GroovityStatistics.startExecution("http(async)");
try {
return f.get();
} finally {
GroovityStatistics.endExecution();
}
}
@Override
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
GroovityStatistics.startExecution("http(async)");
try {
return f.get(timeout, unit);
} finally {
GroovityStatistics.endExecution();
}
}
};
} else {
// return the parsed/handled response object
GroovityStatistics.startExecution("http(sync)");
try {
responseVar = requester.call();
} finally {
GroovityStatistics.endExecution();
}
}
if (varName != null) {
bind(context, varName, responseVar);
}
return responseVar;
}
use of com.disney.groovity.model.ModelJsonWriter in project groovity by disney.
the class WebSocket method call.
/**
* Send a message on this socket; native recognition of Writable, CharSequence, byte[], char[], InputStream, Reader,
* ByteBuffer, File and DataSource, with a fallthrough to JSON serialization
*
* @param message
* @throws IOException
*/
public void call(Object message) throws IOException {
if (!session.isOpen()) {
throw new ClosedChannelException();
}
if (message instanceof Writable) {
try (Writer writer = session.getBasicRemote().getSendWriter()) {
((Writable) message).writeTo(writer);
}
} else if (message instanceof CharSequence) {
try (Writer writer = session.getBasicRemote().getSendWriter()) {
writer.append((CharSequence) message);
}
} else if (message instanceof byte[]) {
session.getBasicRemote().sendBinary(ByteBuffer.wrap((byte[]) message));
} else if (message instanceof char[]) {
try (Writer writer = session.getBasicRemote().getSendWriter()) {
writer.write((char[]) message);
}
} else if (message instanceof InputStream) {
try (InputStream in = (InputStream) message;
OutputStream out = session.getBasicRemote().getSendStream()) {
byte[] buffer = new byte[8192];
int c = 0;
while ((c = in.read(buffer)) != -1) {
out.write(buffer, 0, c);
}
}
} else if (message instanceof Reader) {
try (Reader in = (Reader) message;
Writer out = session.getBasicRemote().getSendWriter()) {
char[] buffer = new char[8192];
int c = 0;
while ((c = in.read(buffer)) != -1) {
out.write(buffer, 0, c);
}
}
} else if (message instanceof ByteBuffer) {
session.getBasicRemote().sendBinary((ByteBuffer) message);
} else if (message instanceof File) {
try (InputStream in = new FileInputStream((File) message);
OutputStream out = session.getBasicRemote().getSendStream()) {
byte[] buffer = new byte[8192];
int c = 0;
while ((c = in.read(buffer)) != -1) {
out.write(buffer, 0, c);
}
}
} else if (message instanceof DataSource) {
try (InputStream in = ((DataSource) message).getInputStream();
OutputStream out = session.getBasicRemote().getSendStream()) {
byte[] buffer = new byte[8192];
int c = 0;
while ((c = in.read(buffer)) != -1) {
out.write(buffer, 0, c);
}
}
} else {
// serialize as json if it's not one of the known text/binary types
try (Writer writer = session.getBasicRemote().getSendWriter()) {
new ModelJsonWriter(writer).visit(message);
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("Error serializing message to websocket ", e);
}
}
}
use of com.disney.groovity.model.ModelJsonWriter in project groovity by disney.
the class Write method tag.
@SuppressWarnings({ "rawtypes", "resource" })
public Object tag(Map attributes, Closure body) throws Exception {
boolean valueDeclared = attributes.containsKey(VALUE);
Object value = null;
if (valueDeclared) {
value = resolve(attributes, VALUE);
if (value == null) {
value = resolve(attributes, "null");
}
}
Object format = resolve(attributes, "format");
Object escape = resolve(attributes, "escape");
Object pretty = resolve(attributes, "pretty");
if (pretty != null && !(pretty instanceof Boolean)) {
pretty = Boolean.valueOf(pretty.toString());
}
Object to = resolve(attributes, "to");
boolean returnTo = true;
if (to == null) {
returnTo = false;
// fall back on body out
to = get(body, OUT);
}
if (to == null) {
throw new IllegalArgumentException("write tag requires valid Writer or String.class for 'to'");
}
Object filter = resolve(attributes, "filter");
Writer writer;
boolean returnString = false;
if (to instanceof Writer) {
writer = (Writer) to;
} else if (to.equals(String.class) || to instanceof CharSequence) {
writer = new CharArrayWriter();
returnString = true;
} else {
throw new IllegalArgumentException("write tag requires valid Writer or String.class for 'to', unrecognized option " + to);
}
if (escape != null) {
String esc = escape.toString();
if (esc.equalsIgnoreCase("xml")) {
writer = new XmlEscapingWriter(writer);
} else if (esc.equalsIgnoreCase("json")) {
writer = new JsonEscapingWriter(writer);
} else if (esc.equalsIgnoreCase("html")) {
writer = new HtmlEscapingWriter(writer);
} else {
throw new IllegalArgumentException("Unrecognized escape value " + esc + ", try xml or json");
}
}
if (value == null) {
Object oldOut = get(body, OUT);
bind(body, OUT, writer);
try {
value = body.call();
} finally {
bind(body, OUT, oldOut);
}
}
if (value != null) {
if (format != null && !"json".equals(format) && !"xml".equals(format)) {
// we don't want to close the formatter because it's not our job to close the writer
Formatter formatter = new Formatter(writer);
if (value instanceof Collection) {
formatter.format(format.toString(), ((Collection) value).toArray());
} else {
formatter.format(format.toString(), value);
}
} else {
if (value instanceof CharSequence) {
writer.append((CharSequence) value);
} else if ((filter == null) && (value instanceof Writable) && (value != body.getOwner())) {
((Writable) value).writeTo(writer);
} else {
ModelWalker mw;
if (format == null) {
Object response = get(body, "response");
if (response != null) {
MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(response.getClass());
MetaProperty mp = mc.hasProperty(response, "contentType");
if (mp != null) {
String ct = (String) mp.getProperty(response);
if (ct != null && ct.contains("xml")) {
format = "xml";
}
}
}
}
if ("xml".equals(format)) {
if (pretty != null && ((Boolean) pretty).booleanValue()) {
mw = new ModelXmlWriter(writer, "\t");
// prevent secondary pretty, just write it pretty up front!
pretty = Boolean.FALSE;
} else {
mw = new ModelXmlWriter(writer);
}
String root = resolve(attributes, "root", String.class);
if (root != null) {
((ModelXmlWriter) mw).setRootElementName(root);
}
@SuppressWarnings("unchecked") Map<String, String> prefixes = resolve(attributes, "namespaces", Map.class);
if (prefixes != null) {
((ModelXmlWriter) mw).setNamespacePrefixes(prefixes);
}
} else {
if (pretty != null && ((Boolean) pretty).booleanValue()) {
mw = new ModelJsonWriter(writer, "\t");
// prevent secondary pretty, just write it pretty up front!
pretty = Boolean.FALSE;
} else {
mw = new ModelJsonWriter(writer);
}
}
if (filter != null) {
ModelFilter[] mfa = null;
if (filter instanceof Collection) {
Collection src = (Collection) filter;
mfa = new ModelFilter[src.size()];
int pos = 0;
for (Object mf : src) {
mfa[pos++] = (ModelFilter) DefaultTypeTransformation.castToType(mf, ModelFilter.class);
}
} else if (filter.getClass().isArray() && filter.getClass().getComponentType().equals(ModelFilter.class)) {
mfa = (ModelFilter[]) filter;
} else if (filter instanceof ModelFilter) {
mfa = new ModelFilter[] { (ModelFilter) filter };
} else {
mfa = new ModelFilter[] { (ModelFilter) DefaultTypeTransformation.castToType(filter, ModelFilter.class) };
}
mw.setFilters(mfa);
}
mw.visit(value);
}
}
}
if (!returnTo) {
return null;
}
Object rval = returnString ? writer.toString() : writer;
if (attributes.get(VAR) != null) {
bind(body, attributes.get(VAR).toString(), rval);
}
return rval;
}
Aggregations