Author: lquack
Date: Fri Sep 16 11:57:11 2016
New Revision: 1761024

URL: http://svn.apache.org/viewvc?rev=1761024&view=rev
Log:
QPID-7382: [Java Broker, WMC] Add Content-Disposition to Message download

merged from trunk with commands:
svn merge -c 1758980 ^/qpid/java/trunk
svn merge -c 1760546 ^/qpid/java/trunk
some merge conflicts which were resolved manually

Modified:
    qpid/java/branches/6.0.x/   (props changed)
    
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
    
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
    
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js
    
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/showMessage.html
    
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/Hello.java
    
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/hello.properties

Propchange: qpid/java/branches/6.0.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Sep 16 11:57:11 2016
@@ -9,5 +9,5 @@
 /qpid/branches/java-broker-vhost-refactor/java:1493674-1494547
 /qpid/branches/java-network-refactor/qpid/java:805429-821809
 /qpid/branches/qpid-2935/qpid/java:1061302-1072333
-/qpid/java/trunk:1715445-1715447,1715586,1715940,1716086-1716087,1716127-1716128,1716141,1716153,1716155,1716194,1716204,1716209,1716227,1716277,1716357,1716368,1716370,1716374,1716432,1716444-1716445,1716455,1716461,1716474,1716489,1716497,1716515,1716555,1716602,1716606-1716610,1716619,1716636,1717269,1717299,1717401,1717446,1717449,1717626,1717691,1717735,1717780,1718744,1718889,1718893,1718918,1718922,1719026,1719028,1719033,1719037,1719047,1719051,1720340,1720664,1721151,1721198,1722019-1722020,1722246,1722339,1722416,1722674,1722678,1722683,1722711,1723064,1723194,1723563,1724216,1724251,1724257,1724292,1724375,1724397,1724432,1724582,1724603,1724780,1724843-1724844,1725295,1725569,1725760,1726176,1726244-1726246,1726249,1726358,1726436,1726449,1726456,1726646,1726653,1726755,1726778,1727532,1727555,1727608,1727951,1727954,1728089,1728167,1728302,1728497,1728501,1728524,1728639,1728651,1728772,1729215,1729297,1729347,1729356,1729406,1729408,1729412,1729515,1729638,1729656-1729
 
657,1729783,1729828,1729832,1729841,1729851,1729886,1729904,1729973,1730019,1730025,1730052,1730072,1730088,1730494,1730499,1730547,1730559,1730567,1730578,1730585,1730651,1730697,1730712-1730713,1730805,1731029,1731110,1731210,1731225,1731444,1731551,1731612,1732184,1732452,1732461,1732465,1732525,1732812,1733467,1734452,1736478,1736751,1736838,1737804,1737835,1737853,1737984,1737992,1738119,1738135,1738231,1738271,1738607,1738610,1738731,1738914,1741702,1742257,1742284,1742339,1742544,1742900,1742926,1743161,1743228,1743383,1743982,1744012-1744013,1744046,1744123,1744157,1744276,1744403,1745424,1745450,1746140,1746273,1747526,1748254,1748723,1748818,1749349,1749399,1749482,1749524,1750359-1750360,1750943,1751433,1754251,1754354,1754392,1754429,1754510,1754550,1755561,1755957,1758628,1758640,1758766,1758964,1759774,1759783,1760032,1760337,1760522
+/qpid/java/trunk:1715445-1715447,1715586,1715940,1716086-1716087,1716127-1716128,1716141,1716153,1716155,1716194,1716204,1716209,1716227,1716277,1716357,1716368,1716370,1716374,1716432,1716444-1716445,1716455,1716461,1716474,1716489,1716497,1716515,1716555,1716602,1716606-1716610,1716619,1716636,1717269,1717299,1717401,1717446,1717449,1717626,1717691,1717735,1717780,1718744,1718889,1718893,1718918,1718922,1719026,1719028,1719033,1719037,1719047,1719051,1720340,1720664,1721151,1721198,1722019-1722020,1722246,1722339,1722416,1722674,1722678,1722683,1722711,1723064,1723194,1723563,1724216,1724251,1724257,1724292,1724375,1724397,1724432,1724582,1724603,1724780,1724843-1724844,1725295,1725569,1725760,1726176,1726244-1726246,1726249,1726358,1726436,1726449,1726456,1726646,1726653,1726755,1726778,1727532,1727555,1727608,1727951,1727954,1728089,1728167,1728302,1728497,1728501,1728524,1728639,1728651,1728772,1729215,1729297,1729347,1729356,1729406,1729408,1729412,1729515,1729638,1729656-1729
 
657,1729783,1729828,1729832,1729841,1729851,1729886,1729904,1729973,1730019,1730025,1730052,1730072,1730088,1730494,1730499,1730547,1730559,1730567,1730578,1730585,1730651,1730697,1730712-1730713,1730805,1731029,1731110,1731210,1731225,1731444,1731551,1731612,1732184,1732452,1732461,1732465,1732525,1732812,1733467,1734452,1736478,1736751,1736838,1737804,1737835,1737853,1737984,1737992,1738119,1738135,1738231,1738271,1738607,1738610,1738731,1738914,1741702,1742257,1742284,1742339,1742544,1742900,1742926,1743161,1743228,1743383,1743982,1744012-1744013,1744046,1744123,1744157,1744276,1744403,1745424,1745450,1746140,1746273,1747526,1748254,1748723,1748818,1749349,1749399,1749482,1749524,1750359-1750360,1750943,1751433,1754251,1754354,1754392,1754429,1754510,1754550,1755561,1755957,1758628,1758640,1758766,1758964,1758980,1759774,1759783,1760032,1760337,1760522,1760546
 /qpid/trunk/qpid:796646-796653

Modified: 
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
URL: 
http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java?rev=1761024&r1=1761023&r2=1761024&view=diff
==============================================================================
--- 
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
 (original)
+++ 
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
 Fri Sep 16 11:57:11 2016
@@ -76,6 +76,16 @@ public interface Queue<X extends Queue<X
     @ManagedContextDefault(name = MAX_ASYNCHRONOUS_DELIVERIES )
     int DEFAULT_MAX_ASYNCHRONOUS_DELIVERIES = 80;
 
+    String MIME_TYPE_TO_FILE_EXTENSION = "qpid.mimeTypeToFileExtension";
+    @SuppressWarnings("unused")
+    @ManagedContextDefault(name = MIME_TYPE_TO_FILE_EXTENSION)
+    String DEFAULT_MIME_TYPE_TO_FILE_EXTENSION = 
"{\"application/json\":\".json\","
+                                                 + 
"\"application/pdf\":\".pdf\","
+                                                 + 
"\"application/xml\":\".xml\","
+                                                 + "\"image/jpeg\":\".jpg\","
+                                                 + "\"image/tiff\":\".tiff\","
+                                                 + "\"text/plain\":\".txt\"}";
+
     @ManagedAttribute
     Exchange getAlternateExchange();
 

Modified: 
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
URL: 
http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java?rev=1761024&r1=1761023&r2=1761024&view=diff
==============================================================================
--- 
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
 (original)
+++ 
qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
 Fri Sep 16 11:57:11 2016
@@ -18,9 +18,14 @@
  */
 package org.apache.qpid.server.queue;
 
+import static 
org.apache.qpid.server.util.ParameterizedTypes.MAP_OF_STRING_STRING;
+
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
 import java.security.AccessControlContext;
 import java.security.AccessControlException;
 import java.security.AccessController;
@@ -143,6 +148,7 @@ public abstract class AbstractQueue<X ex
     };
 
     private static final long INITIAL_TARGET_QUEUE_SIZE = 102400l;
+    private static final String UTF8 = StandardCharsets.UTF_8.name();
 
     private final VirtualHostImpl _virtualHost;
     private final DeletedChildListener _deletedChildListener = new 
DeletedChildListener();
@@ -290,6 +296,7 @@ public abstract class AbstractQueue<X ex
     private boolean _closing;
     private final ConcurrentMap<String, Callable<MessageFilter>> 
_defaultFiltersMap = new ConcurrentHashMap<>();
     private final List<HoldMethod> _holdMethods = new CopyOnWriteArrayList<>();
+    private Map<String, String> _mimeTypeToFileExtension = 
Collections.emptyMap();
 
     private interface HoldMethod
     {
@@ -483,6 +490,7 @@ public abstract class AbstractQueue<X ex
         }
 
         _maxAsyncDeliveries = getContextValue(Integer.class, 
Queue.MAX_ASYNCHRONOUS_DELIVERIES);
+        _mimeTypeToFileExtension = getContextValue(Map.class, 
MAP_OF_STRING_STRING, MIME_TYPE_TO_FILE_EXTENSION);
 
         if(_defaultFilters != null)
         {
@@ -2629,18 +2637,22 @@ public abstract class AbstractQueue<X ex
         }
     }
 
-    public static class MessageContent implements Content, CustomRestHeaders
+    class MessageContent implements Content, CustomRestHeaders
     {
-        public static final int UNLIMITED = -1;
+        private static final int UNLIMITED = -1;
         private final byte[] _data;
         private final String _mimeType;
+        private String _encoding;
+        private long _messageNumber;
         private final long _limit;
 
-        public MessageContent(byte[] data, String mimeType, long limit)
+        MessageContent(byte[] data, String mimeType, final String encoding, 
final long messageNumber, long limit)
         {
             _data = data;
             _mimeType = mimeType;
-            _limit = (limit == UNLIMITED ? data.length : limit);
+            _encoding = encoding;
+            _messageNumber = messageNumber;
+            _limit = (limit == UNLIMITED ? data.length : Math.min(limit, 
data.length));
         }
 
         @Override
@@ -2649,12 +2661,48 @@ public abstract class AbstractQueue<X ex
             outputStream.write(_data, 0, (int) _limit);
         }
 
+        @SuppressWarnings("unused")
         @RestContentHeader("Content-Type")
         public String getContentType()
         {
             return _mimeType;
         }
 
+        @SuppressWarnings("unused")
+        @RestContentHeader("Content-Encoding")
+        public String getContentEncoding()
+        {
+            return _encoding;
+        }
+
+        @SuppressWarnings("unused")
+        @RestContentHeader("Content-Disposition")
+        public String getContentDisposition()
+        {
+            try
+            {
+                String queueName = getName();
+                // replace all non-ascii and non-printable characters and all 
backslashes and percent encoded characters
+                // as suggested by rfc6266 Appendix D
+                String asciiQueueName = queueName.replaceAll("[^\\x20-\\x7E]", 
"?")
+                                                 .replace('\\', '?')
+                                                 
.replaceAll("%[0-9a-fA-F]{2}", "?");
+                String filenameExtension = 
_mimeTypeToFileExtension.get(getContentType());
+                filenameExtension = (filenameExtension == null ? "" : 
filenameExtension);
+                String disposition = String.format("attachment; 
filename=\"%s_msg%09d%s\"; filename*=\"UTF-8''%s_msg%09d%s\"",
+                                                   asciiQueueName,
+                                                   _messageNumber,
+                                                   filenameExtension,
+                                                   
URLEncoder.encode(queueName, UTF8),
+                                                   _messageNumber,
+                                                   filenameExtension);
+                return disposition;
+            }
+            catch (UnsupportedEncodingException e)
+            {
+                throw new RuntimeException("JVM does not support UTF8", e);
+            }
+        }
     }
 
     private static class AcquireAllQueueEntryFilter implements QueueEntryFilter
@@ -3433,7 +3481,11 @@ public abstract class AbstractQueue<X ex
         visit(messageFinder);
         if(messageFinder.isFound())
         {
-            return new MessageContent(messageFinder.getContent(), 
messageFinder.getMimeType(), limit);
+            return new MessageContent(messageFinder.getContent(),
+                                      messageFinder.getMimeType(),
+                                      messageFinder.getEncoding(),
+                                      messageFinder.getMessageNumber(),
+                                      limit);
         }
         else
         {
@@ -3500,6 +3552,7 @@ public abstract class AbstractQueue<X ex
     {
         private final long _messageNumber;
         private String _mimeType;
+        private String _encoding;
         private long _size;
         private byte[] _content;
         private boolean _found;
@@ -3523,6 +3576,7 @@ public abstract class AbstractQueue<X ex
                         try
                         {
                             _mimeType = 
message.getMessageHeader().getMimeType();
+                            _encoding = 
message.getMessageHeader().getEncoding();
                             _size = message.getSize();
                             _content = new byte[(int) _size];
                             _found = true;
@@ -3563,6 +3617,16 @@ public abstract class AbstractQueue<X ex
         {
             return _found;
         }
+
+        public long getMessageNumber()
+        {
+            return _messageNumber;
+        }
+
+        public String getEncoding()
+        {
+            return _encoding;
+        }
     }
 
     private class MessageCollector implements QueueEntryVisitor

Modified: 
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js
URL: 
http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js?rev=1761024&r1=1761023&r2=1761024&view=diff
==============================================================================
--- 
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js
 (original)
+++ 
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js
 Fri Sep 16 11:57:11 2016
@@ -102,34 +102,29 @@ define(["dojo/dom",
                     }
                 }
             }
-            var contentField = query(".message-content", this.dialogNode)[0];
-            populatedFields.push(contentField);
 
             var contentModelObj = {name: "getMessageContent", parent: 
modelObj, type: modelObj.type};
             var parameters = {messageId: data.id};
 
             var url = management.buildObjectURL(contentModelObj, parameters);
-            contentField.innerHTML = '<a href="#" title="' + url + 
'">Download</a><br/><div id="preview"></div>';
 
-            var href = query('a', contentField)[0]
+            var href = query('a#message-download', this.dialogNode)[0];
+            href.title = url;
             connect.connect(href, 'onclick', function ()
             {
                 management.download(contentModelObj, parameters);
             });
 
+            var preview = query('#preview', this.dialogNode)[0];
             if (data.mimeType && data.mimeType.match(/text\/.*/))
             {
                 var limit = 1024;
-                var preview = query('#preview', contentField)[0];
-                preview.innerHTML = 'Preview'
-                                    + (limit < data.size
-                                       ? ' (showing the first ' + limit + ' of 
' + data.size + ' bytes)'
-                                       : ' (showing all ' + data.size + ' 
bytes)')
-                                    + ':<br/>'
-                                    + '<div class="fillRemaining">'
-                                    + '<textarea id="previewContent" readonly 
rows="5" style="width: 100%"></textarea>'
-                                    + '</div>';
-                var previewContent = query("#previewContent", preview)[0];
+                preview.style.display = "block";
+                var previewDetail = query('#preview-detail', preview)[0];
+                previewDetail.innerHTML = (limit < data.size
+                    ? 'showing the first ' + limit + ' of ' + data.size + ' 
bytes'
+                    : 'showing all ' + data.size + ' bytes');
+                var previewContent = query("#message-content-preview", 
preview)[0];
                 var previewParameters = lang.mixin({limit: limit}, parameters);
                 management.load(contentModelObj, previewParameters, {
                         handleAs: "text",
@@ -144,7 +139,9 @@ define(["dojo/dom",
             }
             else
             {
-                registry.byId("showMessage").show();
+                preview.style.display = "none";
+                registry.byId("showMessage")
+                    .show();
             }
         };
 

Modified: 
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/showMessage.html
URL: 
http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/showMessage.html?rev=1761024&r1=1761023&r2=1761024&view=diff
==============================================================================
--- 
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/showMessage.html
 (original)
+++ 
qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/showMessage.html
 Fri Sep 16 11:57:11 2016
@@ -18,7 +18,7 @@
 <div class="dijitHidden">
     <div data-dojo-type="dijit.Dialog" style="width:600px;" 
data-dojo-props="title:'View Message'" id="showMessage">
 
-    <table style="border: 0;">
+    <table style="border: 0; width: 100%">
         <tr style="margin-bottom: 4pt">
             <td style="width: 10em; vertical-align: top"><span 
style="font-weight: bold;">Message Number:</span></td>
             <td><span class="message-id"></span></td>
@@ -70,7 +70,12 @@
 
         <tr style="margin-bottom: 4pt">
             <td style="width: 10em; vertical-align: top"><span 
style="font-weight: bold;">Content:</span></td>
-            <td><div class="message-content"></div></td>
+            <td><a href="#" id="message-download">Download</a><br/>
+                <div id="preview" class="fillRemaining">
+                    Preview (<span id="preview-detail"></span>):<br/>
+                    <textarea id="message-content-preview" readonly rows="5" 
style="width: 100%"></textarea>
+                </div>
+            </td>
         </tr>
     </table>
         <br/>

Modified: 
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/Hello.java
URL: 
http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/Hello.java?rev=1761024&r1=1761023&r2=1761024&view=diff
==============================================================================
--- 
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/Hello.java
 (original)
+++ 
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/Hello.java
 Fri Sep 16 11:57:11 2016
@@ -27,6 +27,7 @@ import java.util.Properties;
 import javax.jms.Connection;
 import javax.jms.ConnectionFactory;
 import javax.jms.Destination;
+import javax.jms.MapMessage;
 import javax.jms.MessageConsumer;
 import javax.jms.MessageProducer;
 import javax.jms.Session;
@@ -61,7 +62,7 @@ public class Hello
             connection.start();
 
             Session session = connection.createSession(false, 
Session.AUTO_ACKNOWLEDGE);
-            Destination destination = (Destination) 
context.lookup("topicExchange");
+            Destination destination = (Destination) context.lookup("myQueue");
 
             MessageProducer messageProducer = 
session.createProducer(destination);
             MessageConsumer messageConsumer = 
session.createConsumer(destination);
@@ -69,6 +70,26 @@ public class Hello
             TextMessage message = session.createTextMessage("Hello world!");
             messageProducer.send(message);
 
+            MapMessage mm = session.createMapMessage();
+            mm.setBoolean("b", true);
+            mm.setString("s", "fnord");
+            mm.setLong("l", 123456789123L);
+            messageProducer.send(mm);
+
+            TextMessage longMessage = session.createTextMessage("LongMessage\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n"
+                                                                + 
"0123456789112345678921234567893123456789412345678951234567896123456789712345678981234567899123456789\n");
+            messageProducer.send(longMessage);
+
             message = (TextMessage)messageConsumer.receive();
             System.out.println(message.getText());
 

Modified: 
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/hello.properties
URL: 
http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/hello.properties?rev=1761024&r1=1761023&r2=1761024&view=diff
==============================================================================
--- 
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/hello.properties
 (original)
+++ 
qpid/java/branches/6.0.x/client/example/src/main/java/org/apache/qpid/example/hello.properties
 Fri Sep 16 11:57:11 2016
@@ -25,3 +25,4 @@ connectionfactory.qpidConnectionfactory
 # Register an AMQP destination in JNDI
 # destination.[jniName] = [Address Format]
 destination.topicExchange = amq.topic
+queue.myQueue = testQueue



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to