1
1
/*
2
- * Copyright 2002-2014 the original author or authors.
2
+ * Copyright 2002-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .messaging .simp .stomp ;
18
18
19
-
20
19
import java .nio .ByteBuffer ;
21
20
import java .util .Collections ;
22
21
import java .util .List ;
28
27
import org .springframework .util .LinkedMultiValueMap ;
29
28
import org .springframework .util .MultiValueMap ;
30
29
31
-
32
30
/**
33
31
* An extension of {@link org.springframework.messaging.simp.stomp.StompDecoder}
34
32
* that buffers content remaining in the input ByteBuffer after the parent
45
43
*
46
44
* @author Rossen Stoyanchev
47
45
* @since 4.0.3
46
+ * @see StompDecoder
48
47
*/
49
48
public class BufferingStompDecoder {
50
49
@@ -57,78 +56,57 @@ public class BufferingStompDecoder {
57
56
private volatile Integer expectedContentLength ;
58
57
59
58
59
+ /**
60
+ * Create a new {@code BufferingStompDecoder} wrapping the given {@code StompDecoder}.
61
+ * @param stompDecoder the target decoder to wrap
62
+ * @param bufferSizeLimit the buffer size limit
63
+ */
60
64
public BufferingStompDecoder (StompDecoder stompDecoder , int bufferSizeLimit ) {
61
- Assert .notNull (stompDecoder , "'stompDecoder' is required" );
62
- Assert .isTrue (bufferSizeLimit > 0 , "Buffer size must be greater than 0" );
65
+ Assert .notNull (stompDecoder , "StompDecoder is required" );
66
+ Assert .isTrue (bufferSizeLimit > 0 , "Buffer size limit must be greater than 0" );
63
67
this .stompDecoder = stompDecoder ;
64
68
this .bufferSizeLimit = bufferSizeLimit ;
65
69
}
66
70
67
71
68
72
/**
69
- * Return the wrapped
70
- * {@link org.springframework.messaging.simp.stomp.StompDecoder}.
73
+ * Return the wrapped {@link StompDecoder}.
71
74
*/
72
- public StompDecoder getStompDecoder () {
75
+ public final StompDecoder getStompDecoder () {
73
76
return this .stompDecoder ;
74
77
}
75
78
76
79
/**
77
80
* Return the configured buffer size limit.
78
81
*/
79
- public int getBufferSizeLimit () {
82
+ public final int getBufferSizeLimit () {
80
83
return this .bufferSizeLimit ;
81
84
}
82
85
83
- /**
84
- * Calculate the current buffer size.
85
- */
86
- public int getBufferSize () {
87
- int size = 0 ;
88
- for (ByteBuffer buffer : this .chunks ) {
89
- size = size + buffer .remaining ();
90
- }
91
- return size ;
92
- }
93
-
94
- /**
95
- * Get the expected content length of the currently buffered, incomplete STOMP frame.
96
- */
97
- public Integer getExpectedContentLength () {
98
- return this .expectedContentLength ;
99
- }
100
-
101
86
102
87
/**
103
88
* Decodes one or more STOMP frames from the given {@code ByteBuffer} into a
104
89
* list of {@link Message}s.
105
- *
106
90
* <p>If there was enough data to parse a "content-length" header, then the
107
91
* value is used to determine how much more data is needed before a new
108
92
* attempt to decode is made.
109
- *
110
93
* <p>If there was not enough data to parse the "content-length", or if there
111
94
* is "content-length" header, every subsequent call to decode attempts to
112
95
* parse again with all available data. Therefore the presence of a "content-length"
113
96
* header helps to optimize the decoding of large messages.
114
- *
115
97
* @param newBuffer a buffer containing new data to decode
116
- *
117
98
* @return decoded messages or an empty list
118
99
* @throws StompConversionException raised in case of decoding issues
119
100
*/
120
101
public List <Message <byte []>> decode (ByteBuffer newBuffer ) {
121
-
122
102
this .chunks .add (newBuffer );
123
-
124
103
checkBufferLimits ();
125
104
126
105
if (getExpectedContentLength () != null && getBufferSize () < this .expectedContentLength ) {
127
106
return Collections .<Message <byte []>>emptyList ();
128
107
}
129
108
130
109
ByteBuffer bufferToDecode = assembleChunksAndReset ();
131
-
132
110
MultiValueMap <String , String > headers = new LinkedMultiValueMap <String , String >();
133
111
List <Message <byte []>> messages = this .stompDecoder .decode (bufferToDecode , headers );
134
112
@@ -140,21 +118,6 @@ public List<Message<byte[]>> decode(ByteBuffer newBuffer) {
140
118
return messages ;
141
119
}
142
120
143
- private void checkBufferLimits () {
144
- if (getExpectedContentLength () != null ) {
145
- if (getExpectedContentLength () > getBufferSizeLimit ()) {
146
- throw new StompConversionException (
147
- "The 'content-length' header " + getExpectedContentLength () +
148
- " exceeds the configured message buffer size limit " + getBufferSizeLimit ());
149
- }
150
- }
151
- if (getBufferSize () > getBufferSizeLimit ()) {
152
- throw new StompConversionException ("The configured stomp frame buffer size limit of " +
153
- getBufferSizeLimit () + " bytes has been exceeded" );
154
-
155
- }
156
- }
157
-
158
121
private ByteBuffer assembleChunksAndReset () {
159
122
ByteBuffer result ;
160
123
if (this .chunks .size () == 1 ) {
@@ -172,4 +135,36 @@ private ByteBuffer assembleChunksAndReset() {
172
135
return result ;
173
136
}
174
137
138
+ private void checkBufferLimits () {
139
+ if (this .expectedContentLength != null ) {
140
+ if (this .expectedContentLength > this .bufferSizeLimit ) {
141
+ throw new StompConversionException (
142
+ "'content-length' header value " + this .expectedContentLength +
143
+ " exceeds configured message buffer size limit " + this .bufferSizeLimit );
144
+ }
145
+ }
146
+ if (getBufferSize () > this .bufferSizeLimit ) {
147
+ throw new StompConversionException ("The configured stomp frame buffer size limit of " +
148
+ this .bufferSizeLimit + " bytes has been exceeded" );
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Calculate the current buffer size.
154
+ */
155
+ public int getBufferSize () {
156
+ int size = 0 ;
157
+ for (ByteBuffer buffer : this .chunks ) {
158
+ size = size + buffer .remaining ();
159
+ }
160
+ return size ;
161
+ }
162
+
163
+ /**
164
+ * Get the expected content length of the currently buffered, incomplete STOMP frame.
165
+ */
166
+ public Integer getExpectedContentLength () {
167
+ return this .expectedContentLength ;
168
+ }
169
+
175
170
}
0 commit comments