/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.ext.json; import java.io.IOException; import org.restlet.data.MediaType; import org.restlet.data.Status; import org.restlet.engine.io.IoUtils; import org.restlet.representation.Representation; import org.restlet.representation.WriterRepresentation; /** * Wrappers that adds a JSONP header and footer to JSON representations. The * goal is to make them accessible to web browser without restriction from * single origin policies. * * @author Mark Kharitonov * @author Jerome Louvel */ public class JsonpRepresentation extends WriterRepresentation { /** The name of the JavaScript callback method. */ private final String callback; /** The actual status code. */ private final Status status; /** The wrapped JSON representation. */ private final Representation wrappedRepresentation; /** * Constructor. * * @param callback * The name of the JavaScript callback method. * @param status * The actual status code. * @param wrappedRepresentation */ public JsonpRepresentation(String callback, Status status, Representation wrappedRepresentation) { super(MediaType.APPLICATION_JAVASCRIPT); this.callback = callback; this.status = status; this.wrappedRepresentation = wrappedRepresentation; } /** * Returns the name of the JavaScript callback method. * * @return The name of the JavaScript callback method. */ public String getCallback() { return callback; } @Override public long getSize() { long result = wrappedRepresentation.getSize(); if (result > 0 && MediaType.APPLICATION_JSON.equals(wrappedRepresentation .getMediaType())) { try { java.io.StringWriter sw = new java.io.StringWriter(); write(sw); sw.flush(); return sw.toString().length(); } catch (IOException e) { return UNKNOWN_SIZE; } } return UNKNOWN_SIZE; } /** * Returns the actual status code. * * @return The actual status code. */ public Status getStatus() { return status; } @Override public void write(java.io.Writer writer) throws IOException { writer.write(getCallback()); writer.write("({\"status\":"); writer.write(Integer.toString(getStatus().getCode())); writer.write(",\"body\":"); if (MediaType.APPLICATION_JSON.equals(wrappedRepresentation .getMediaType())) { IoUtils.copy(wrappedRepresentation.getReader(), writer); } else { writer.write("\""); String text = wrappedRepresentation.getText(); if (text.indexOf('\"') >= 0) { text = text.replace("\"", "\\\""); } writer.write(text); writer.write("\""); } writer.write("});"); } }