Search in sources :

Example 1 with ModelJsonWriter

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);
}
Also used : ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) Map(java.util.Map) CharArrayWriter(java.io.CharArrayWriter) Test(org.junit.Test)

Example 2 with ModelJsonWriter

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;
}
Also used : Entry(java.util.Map.Entry) HttpPost(org.apache.http.client.methods.HttpPost) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) MultipartEntityBuilder(org.apache.http.entity.mime.MultipartEntityBuilder) ContentType(org.apache.http.entity.ContentType) ResponseHandler(org.apache.http.client.ResponseHandler) HttpOptions(org.apache.http.client.methods.HttpOptions) ArrayList(java.util.ArrayList) Writable(groovy.lang.Writable) BasicAuthCache(org.apache.http.impl.client.BasicAuthCache) Document(org.w3c.dom.Document) HttpPut(org.apache.http.client.methods.HttpPut) ClientProtocolException(org.apache.http.client.ClientProtocolException) StringEntity(org.apache.http.entity.StringEntity) ByteArrayEntity(org.apache.http.entity.ByteArrayEntity) HttpEntityEnclosingRequest(org.apache.http.HttpEntityEnclosingRequest) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ArrayList(java.util.ArrayList) TimeoutException(java.util.concurrent.TimeoutException) Binding(groovy.lang.Binding) RequestConfig(org.apache.http.client.config.RequestConfig) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) UrlEncodedFormEntity(org.apache.http.client.entity.UrlEncodedFormEntity) URIBuilder(org.apache.http.client.utils.URIBuilder) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials) BasicCookieStore(org.apache.http.impl.client.BasicCookieStore) Header(org.apache.http.Header) ContentBody(org.apache.http.entity.mime.content.ContentBody) HttpRequestInterceptor(org.apache.http.HttpRequestInterceptor) AuthScope(org.apache.http.auth.AuthScope) ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) ScriptHelper(com.disney.groovity.util.ScriptHelper) Map(java.util.Map) File(java.io.File) HttpEntity(org.apache.http.HttpEntity) HttpDelete(org.apache.http.client.methods.HttpDelete) HttpGet(org.apache.http.client.methods.HttpGet) Element(org.w3c.dom.Element) HttpResponseException(org.apache.http.client.HttpResponseException) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) HttpHead(org.apache.http.client.methods.HttpHead) CharArrayWriter(java.io.CharArrayWriter) Callable(java.util.concurrent.Callable) Function(java.util.function.Function) Entry(java.util.Map.Entry) StringWriter(java.io.StringWriter) HttpSignatureSigner(com.disney.http.auth.client.signer.HttpSignatureSigner) Iterator(java.util.Iterator) GPathResult(groovy.util.slurpersupport.GPathResult) ExecutionException(java.util.concurrent.ExecutionException) NameValuePair(org.apache.http.NameValuePair) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) FileEntity(org.apache.http.entity.FileEntity) InputStream(java.io.InputStream) HttpResponse(org.apache.http.HttpResponse) UserPass(com.disney.groovity.tags.Credentials.UserPass) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) CredentialsProvider(org.apache.http.client.CredentialsProvider) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) TimeoutException(java.util.concurrent.TimeoutException) ClientProtocolException(org.apache.http.client.ClientProtocolException) HttpResponseException(org.apache.http.client.HttpResponseException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) InputStreamEntity(org.apache.http.entity.InputStreamEntity)

Example 3 with ModelJsonWriter

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);
        }
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Writable(groovy.lang.Writable) Reader(java.io.Reader) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) FileInputStream(java.io.FileInputStream) ClosedChannelException(java.nio.channels.ClosedChannelException) IOException(java.io.IOException) DataSource(javax.activation.DataSource) ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) File(java.io.File) CharArrayWriter(java.io.CharArrayWriter) ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) Writer(java.io.Writer)

Example 4 with ModelJsonWriter

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;
}
Also used : ModelFilter(com.disney.groovity.model.ModelFilter) Formatter(java.util.Formatter) Writable(groovy.lang.Writable) ModelWalker(com.disney.groovity.model.ModelWalker) CharArrayWriter(java.io.CharArrayWriter) HtmlEscapingWriter(com.disney.groovity.util.HtmlEscapingWriter) MetaClass(groovy.lang.MetaClass) ModelXmlWriter(com.disney.groovity.model.ModelXmlWriter) Collection(java.util.Collection) XmlEscapingWriter(com.disney.groovity.util.XmlEscapingWriter) JsonEscapingWriter(com.disney.groovity.util.JsonEscapingWriter) ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) MetaProperty(groovy.lang.MetaProperty) Map(java.util.Map) CharArrayWriter(java.io.CharArrayWriter) JsonEscapingWriter(com.disney.groovity.util.JsonEscapingWriter) ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) Writer(java.io.Writer) ModelXmlWriter(com.disney.groovity.model.ModelXmlWriter) HtmlEscapingWriter(com.disney.groovity.util.HtmlEscapingWriter) XmlEscapingWriter(com.disney.groovity.util.XmlEscapingWriter)

Aggregations

ModelJsonWriter (com.disney.groovity.model.ModelJsonWriter)4 CharArrayWriter (java.io.CharArrayWriter)4 Writable (groovy.lang.Writable)3 Map (java.util.Map)3 File (java.io.File)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 Writer (java.io.Writer)2 ModelFilter (com.disney.groovity.model.ModelFilter)1 ModelWalker (com.disney.groovity.model.ModelWalker)1 ModelXmlWriter (com.disney.groovity.model.ModelXmlWriter)1 UserPass (com.disney.groovity.tags.Credentials.UserPass)1 HtmlEscapingWriter (com.disney.groovity.util.HtmlEscapingWriter)1 JsonEscapingWriter (com.disney.groovity.util.JsonEscapingWriter)1 ScriptHelper (com.disney.groovity.util.ScriptHelper)1 XmlEscapingWriter (com.disney.groovity.util.XmlEscapingWriter)1 HttpSignatureSigner (com.disney.http.auth.client.signer.HttpSignatureSigner)1 Binding (groovy.lang.Binding)1 MetaClass (groovy.lang.MetaClass)1 MetaProperty (groovy.lang.MetaProperty)1