dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #30957
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15742: add support for jsonp
------------------------------------------------------------
revno: 15742
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2014-06-18 11:05:19 +0200
message:
add support for jsonp
added:
dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonPMessageConverter.java
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNodeSerializer.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java
dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonMessageConverter.java
dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/XmlMessageConverter.java
dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/view/CustomPathExtensionContentNegotiationStrategy.java
dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/servlet.xml
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNodeSerializer.java 2014-06-17 14:33:44 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNodeSerializer.java 2014-06-18 09:05:19 +0000
@@ -51,7 +51,7 @@
protected abstract void flushStream() throws Exception;
- private Config config;
+ protected Config config;
@Override
public void serialize( RootNode rootNode, OutputStream outputStream ) throws Exception
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java 2014-06-17 14:33:44 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java 2014-06-18 09:05:19 +0000
@@ -28,6 +28,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
@@ -40,6 +44,12 @@
*/
private InclusionStrategy inclusionStrategy = InclusionStrategy.Include.NON_NULL;
+ /**
+ * Property map that can hold any key=value pair, can be used to set custom
+ * properties that only certain serializers know about.
+ */
+ private final Map<String, Object> properties = Maps.newHashMap();
+
public Config()
{
}
@@ -53,4 +63,9 @@
{
this.inclusionStrategy = inclusionStrategy;
}
+
+ public Map<String, Object> getProperties()
+ {
+ return properties;
+ }
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java 2014-06-17 14:06:57 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java 2014-06-18 09:05:19 +0000
@@ -48,11 +48,13 @@
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
@Component
-@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
+@Scope( value = "prototype", proxyMode = ScopedProxyMode.INTERFACES )
public class Jackson2JsonNodeSerializer extends AbstractNodeSerializer
{
public static final String CONTENT_TYPE = "application/json";
+ public static final String JSONP_CALLBACK = "org.hisp.dhis.node.serializers.Jackson2JsonNodeSerializer.callback";
+
private final static ObjectMapper objectMapper = new ObjectMapper();
static
@@ -86,7 +88,11 @@
@Override
protected void startWriteRootNode( RootNode rootNode ) throws Exception
{
- //generator.writeRaw( "callback(" );
+ if ( config.getProperties().containsKey( JSONP_CALLBACK ) )
+ {
+ generator.writeRaw( config.getProperties().get( JSONP_CALLBACK ) + "(" );
+ }
+
generator.writeStartObject();
}
@@ -94,7 +100,11 @@
protected void endWriteRootNode( RootNode rootNode ) throws Exception
{
generator.writeEndObject();
- //generator.writeRaw( ")" );
+
+ if ( config.getProperties().containsKey( JSONP_CALLBACK ) )
+ {
+ generator.writeRaw( ")" );
+ }
}
@Override
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonMessageConverter.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonMessageConverter.java 2014-06-18 07:15:48 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonMessageConverter.java 2014-06-18 09:05:19 +0000
@@ -41,7 +41,6 @@
import org.springframework.stereotype.Component;
import java.io.IOException;
-import java.nio.charset.Charset;
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -49,13 +48,13 @@
@Component
public class JsonMessageConverter extends AbstractHttpMessageConverter<RootNode>
{
+ public static final ImmutableList<MediaType> SUPPORTED_MEDIA_TYPES = ImmutableList.<MediaType>builder()
+ .add( new MediaType( "application", "json" ) )
+ .build();
+
@Autowired
private NodeService nodeService;
- public final ImmutableList<MediaType> SUPPORTED_MEDIA_TYPES = ImmutableList.<MediaType>builder()
- .add( new MediaType( "application", "json", Charset.forName( "UTF-8" ) ) )
- .build();
-
public JsonMessageConverter()
{
setSupportedMediaTypes( SUPPORTED_MEDIA_TYPES );
=== added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonPMessageConverter.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonPMessageConverter.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/JsonPMessageConverter.java 2014-06-18 09:05:19 +0000
@@ -0,0 +1,112 @@
+package org.hisp.dhis.webapi.messageconverter;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.hisp.dhis.node.NodeService;
+import org.hisp.dhis.node.serializers.Jackson2JsonNodeSerializer;
+import org.hisp.dhis.node.types.RootNode;
+import org.hisp.dhis.webapi.service.ContextService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpInputMessage;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.AbstractHttpMessageConverter;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Component
+public class JsonPMessageConverter extends AbstractHttpMessageConverter<RootNode>
+{
+ public static final String DEFAULT_CALLBACK_PARAMETER = "callback";
+
+ public static final ImmutableList<MediaType> SUPPORTED_MEDIA_TYPES = ImmutableList.<MediaType>builder()
+ .add( new MediaType( "application", "javascript" ) )
+ .add( new MediaType( "application", "x-javascript" ) )
+ .add( new MediaType( "text", "javascript" ) )
+ .build();
+
+ @Autowired
+ private NodeService nodeService;
+
+ @Autowired
+ private ContextService contextService;
+
+ public JsonPMessageConverter()
+ {
+ setSupportedMediaTypes( SUPPORTED_MEDIA_TYPES );
+ }
+
+ @Override
+ protected boolean supports( Class<?> clazz )
+ {
+ return RootNode.class.equals( clazz );
+ }
+
+ @Override
+ protected boolean canRead( MediaType mediaType )
+ {
+ return false;
+ }
+
+ @Override
+ protected RootNode readInternal( Class<? extends RootNode> clazz, HttpInputMessage inputMessage ) throws IOException, HttpMessageNotReadableException
+ {
+ return null;
+ }
+
+ @Override
+ protected void writeInternal( RootNode rootNode, HttpOutputMessage outputMessage ) throws IOException, HttpMessageNotWritableException
+ {
+ List<String> callbacks = Lists.newArrayList( contextService.getParameterValues( DEFAULT_CALLBACK_PARAMETER ) );
+
+ String callbackParam;
+
+ if ( callbacks.isEmpty() )
+ {
+ callbackParam = DEFAULT_CALLBACK_PARAMETER;
+ }
+ else
+ {
+ callbackParam = callbacks.get( 0 );
+ }
+
+ rootNode.getConfig().getProperties().put( Jackson2JsonNodeSerializer.JSONP_CALLBACK, callbackParam );
+
+ nodeService.serialize( rootNode, "application/json", outputMessage.getBody() );
+ }
+}
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/XmlMessageConverter.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/XmlMessageConverter.java 2014-06-18 07:15:48 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/messageconverter/XmlMessageConverter.java 2014-06-18 09:05:19 +0000
@@ -41,7 +41,6 @@
import org.springframework.stereotype.Component;
import java.io.IOException;
-import java.nio.charset.Charset;
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -49,14 +48,14 @@
@Component
public class XmlMessageConverter extends AbstractHttpMessageConverter<RootNode>
{
+ public static final ImmutableList<MediaType> SUPPORTED_MEDIA_TYPES = ImmutableList.<MediaType>builder()
+ .add( new MediaType( "application", "xml" ) )
+ .add( new MediaType( "text", "xml" ) )
+ .build();
+
@Autowired
private NodeService nodeService;
- public final ImmutableList<MediaType> SUPPORTED_MEDIA_TYPES = ImmutableList.<MediaType>builder()
- .add( new MediaType( "application", "xml", Charset.forName( "UTF-8" ) ) )
- .add( new MediaType( "text", "xml", Charset.forName( "UTF-8" ) ) )
- .build();
-
public XmlMessageConverter()
{
setSupportedMediaTypes( SUPPORTED_MEDIA_TYPES );
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/view/CustomPathExtensionContentNegotiationStrategy.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/view/CustomPathExtensionContentNegotiationStrategy.java 2014-05-22 12:40:24 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/view/CustomPathExtensionContentNegotiationStrategy.java 2014-06-18 09:05:19 +0000
@@ -99,5 +99,4 @@
}
return path.substring( extIndex + 1 );
}
-
}
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/servlet.xml'
--- dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/servlet.xml 2014-06-18 07:15:48 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/servlet.xml 2014-06-18 09:05:19 +0000
@@ -23,10 +23,11 @@
</constructor-arg>
</bean>
- <mvc:annotation-driven>
+ <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="true">
+ <ref bean="jsonMessageConverter" />
+ <ref bean="jsonPMessageConverter" />
<ref bean="xmlMessageConverter" />
- <ref bean="jsonMessageConverter" />
<ref bean="org.hisp.dhis.webapi.utils.RenderServiceMessageConverter" />
<bean class="org.hisp.dhis.api.mobile.support.DataStreamSerializableMessageConverter" />
</mvc:message-converters>
@@ -41,7 +42,7 @@
<bean id="headerContentNegotiationStrategy" class="org.springframework.web.accept.HeaderContentNegotiationStrategy" />
- <bean id="pathExtensionContentNegotiationStrategy" class="org.hisp.dhis.webapi.view.CustomPathExtensionContentNegotiationStrategy">
+ <bean id="customPathExtensionContentNegotiationStrategy" class="org.hisp.dhis.webapi.view.CustomPathExtensionContentNegotiationStrategy">
<constructor-arg name="mediaTypes">
<map>
<entry key="json" value="application/json" />
@@ -55,12 +56,28 @@
<entry key="csv" value="application/csv" />
</map>
</constructor-arg>
+ <property name="useJaf" value="false" />
+ </bean>
+
+ <bean id="parameterContentNegotiationStrategy" class="org.springframework.web.accept.ParameterContentNegotiationStrategy">
+ <constructor-arg name="mediaTypes">
+ <map>
+ <entry key="json" value="application/json" />
+ <entry key="jsonp" value="application/javascript" />
+ <entry key="xml" value="application/xml" />
+ <entry key="png" value="image/png" />
+ <entry key="pdf" value="application/pdf" />
+ <entry key="xls" value="application/vnd.ms-excel" />
+ <entry key="csv" value="application/csv" />
+ </map>
+ </constructor-arg>
</bean>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManager">
<constructor-arg>
<list>
- <ref bean="pathExtensionContentNegotiationStrategy" />
+ <ref bean="customPathExtensionContentNegotiationStrategy" />
+ <ref bean="parameterContentNegotiationStrategy" />
<ref bean="headerContentNegotiationStrategy" />
<ref bean="fixedContentNegotiationStrategy" />
</list>