cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: [cxf] branch master updated: [CXF-7532]REST on JMS transport can't handle the request message with text messageType
Date Fri, 20 Oct 2017 09:32:16 GMT
Thanks Freeman, it looks fine, yes, it's a bit tricky to make sure it 
works across all of JAX-RS providers, especially with custom MBRs 
expecting InputStream to be not null...

Sergey

On 20/10/17 03:08, Freeman Fang wrote:
> Hi Sergey,
> 
> Cleaned up accordingly.
> 
> Cheers
> -------------
> Freeman(Yue) Fang
> 
> Red Hat, Inc.
> FuseSource is now part of Red Hat
> 
> 
> 
>> On Oct 20, 2017, at 5:59 AM, Sergey Beryozkin <sberyozkin@gmail.com 
>> <mailto:sberyozkin@gmail.com>> wrote:
>>
>> Some JAX-RS providers check Reader or XMLStreamReader if InputStream 
>> is null.
>> But at the moment, Freeman, please do a bit of cleanup as agreed, and 
>> then we can check if the use ReaderInputStream can be avoided at all.
>>
>> Sergey
>>
>> On 19/10/17 19:47, Daniel Kulp wrote:
>>> If using the TEXT stuff for JMS, it should remain as a Reader on the 
>>> message if at all possible.  Converting from Reader to InputStream is 
>>> not a trivial operation and does enact a performance penalty.   All 
>>> of the SOAP pathways for JMS should be OK for use of a Reader so that 
>>> we can avoid the entire String->UTF-8 bytes->chars round tripping.
>>> Dan
>>> On Oct 19, 2017, at 5:21 AM, ffang <freeman.fang@gmail.com 
>>> <mailto:freeman.fang@gmail.com>> wrote:
>>>>
>>>> I modified the JMS transport part and set ReaderInputStream instead 
>>>> of Reader, running all tests now, will see what I can get.
>>>>
>>>> If I run into any test failure, I will keep things as is, just clean up.
>>>> -------------
>>>> Freeman(Yue) Fang
>>>>
>>>> Red Hat, Inc.
>>>> FuseSource is now part of Red Hat
>>>>
>>>>
>>>>
>>>>> On Oct 19, 2017, at 5:16 PM, Sergey Beryozkin <sberyozkin@gmail.com 
>>>>> <mailto:sberyozkin@gmail.com>> wrote:
>>>>>
>>>>> If we assume that checking Reader can be useful in the general 
>>>>> sense, then may be lets keep things as is, with the minor cleanup 
>>>>> only...
>>>>>
>>>>> Sergey
>>>>> On 19/10/17 10:05, Sergey Beryozkin wrote:
>>>>>> Hi Freeman
>>>>>> Reader may likely need to be set too for SOAP, and I recall 
>>>>>> checking Reader somewhere else too (will double check now), but I 
>>>>>> thought may be the transport can set both Reader and InputStream, 
>>>>>> hmm, that is an extra instance though, may be lets start with 
>>>>>> moving ReaderInputStream to the core first ?
>>>>>> Sergey
>>>>>> On 19/10/17 09:59, ffang wrote:
>>>>>>> Yeah, set ReaderInputStream instead of Reader for the JMS 
>>>>>>> transport is a better solution. If no objection I will go this way.
>>>>>>> -------------
>>>>>>> Freeman(Yue) Fang
>>>>>>>
>>>>>>> Red Hat, Inc.
>>>>>>> FuseSource is now part of Red Hat
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> On Oct 19, 2017, at 4:50 PM, Sergey Beryozkin 
>>>>>>>> <sberyozkin@gmail.com <mailto:sberyozkin@gmail.com> 
>>>>>>>> <mailto:sberyozkin@gmail.com>> wrote:
>>>>>>>>
>>>>>>>> The other thing is, should JMS transport itself set 
>>>>>>>> ReaderInputStream as InputStream on the message, as opposed to 
>>>>>>>> patching the JAX-RS code in various places ?
>>>>>>>>
>>>>>>>> Sergey
>>>>>>>> On 19/10/17 09:44, Sergey Beryozkin wrote:
>>>>>>>>> Hi Freeman
>>>>>>>>> Can you move ReaderInputStream to the CXF core where 
>>>>>>>>> CachedInputStream and other IO utility code is located ?
>>>>>>>>> Please also update the code which gets Reader.class and check 
>>>>>>>>> it for null first, and also drop a comment re the JMS 
>>>>>>>>> transport, checking the reader can make sense in all the cases...
>>>>>>>>> Thanks, Sergey
>>>>>>>>> On 19/10/17 04:16, ffang@apache.org <mailto:ffang@apache.org> 
>>>>>>>>> <mailto:ffang@apache.org> wrote:
>>>>>>>>>> This is an automated email from the ASF dual-hosted git 
>>>>>>>>>> repository.
>>>>>>>>>>
>>>>>>>>>> ffang pushed a commit to branch master
>>>>>>>>>> in repository https://gitbox.apache.org/repos/asf/cxf.git
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> The following commit(s) were added to refs/heads/master by 
>>>>>>>>>> this push:
>>>>>>>>>>      new 1d66475  [CXF-7532]REST on JMS transport can't handle 
>>>>>>>>>> the request message with text messageType
>>>>>>>>>> 1d66475 is described below
>>>>>>>>>>
>>>>>>>>>> commit 1d66475b4dea2a0031dcb1765e8e9fd08430ec9b
>>>>>>>>>> Author: Freeman Fang <freeman.fang@gmail.com 
>>>>>>>>>> <mailto:freeman.fang@gmail.com> <mailto:freeman.fang@gmail.com>>
>>>>>>>>>> AuthorDate: Thu Oct 19 11:15:50 2017 +0800
>>>>>>>>>>
>>>>>>>>>>     [CXF-7532]REST on JMS transport can't handle the request 
>>>>>>>>>> message with text messageType
>>>>>>>>>> ---
>>>>>>>>>>  .../org/apache/cxf/jaxrs/impl/ResponseImpl.java    |   5 +
>>>>>>>>>>  .../org/apache/cxf/jaxrs/utils/JAXRSUtils.java     |   6 +-
>>>>>>>>>>  .../apache/cxf/jaxrs/utils/ReaderInputStream.java  | 296 
>>>>>>>>>> +++++++++++++++++++++
>>>>>>>>>>  .../apache/cxf/systest/jaxrs/jms/JAXRSJmsTest.java |  90 +++++++
>>>>>>>>>>  4 files changed, 396 insertions(+), 1 deletion(-)
>>>>>>>>>>
>>>>>>>>>> diff --git 
>>>>>>>>>> a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java 
>>>>>>>>>> b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
>>>>>>>>>> index e3a3acf..82f183a 100644
>>>>>>>>>> --- 
>>>>>>>>>> a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
>>>>>>>>>> +++ 
>>>>>>>>>> b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
>>>>>>>>>> @@ -58,6 +58,7 @@ import 
>>>>>>>>>> org.apache.cxf.jaxrs.provider.ProviderFactory;
>>>>>>>>>>  import org.apache.cxf.jaxrs.utils.HttpUtils;
>>>>>>>>>>  import org.apache.cxf.jaxrs.utils.InjectionUtils;
>>>>>>>>>>  import org.apache.cxf.jaxrs.utils.JAXRSUtils;
>>>>>>>>>> +import org.apache.cxf.jaxrs.utils.ReaderInputStream;
>>>>>>>>>>  import org.apache.cxf.message.Message;
>>>>>>>>>>  import org.apache.cxf.message.MessageUtils;
>>>>>>>>>> @@ -342,6 +343,10 @@ public final class ResponseImpl extends 
>>>>>>>>>> Response {
>>>>>>>>>>              entityStreamAvailable = entityStream != null;
>>>>>>>>>>          } else if (entity instanceof InputStream) {
>>>>>>>>>>              entityStream = InputStream.class.cast(entity);
>>>>>>>>>> +        } else {
>>>>>>>>>> +            Message inMessage = getResponseMessage();
>>>>>>>>>> +            Reader reader = inMessage.getContent(Reader.class);
>>>>>>>>>> +            entityStream = InputStream.class.cast(new 
>>>>>>>>>> ReaderInputStream(reader));
>>>>>>>>>>          }
>>>>>>>>>>          // we need to check for readers even if no IS is set 
>>>>>>>>>> - the readers may still do it
>>>>>>>>>> diff --git 
>>>>>>>>>> a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java 
>>>>>>>>>> b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
>>>>>>>>>> index 0ef6565..509f76d 100644
>>>>>>>>>> --- 
>>>>>>>>>> a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
>>>>>>>>>> +++ 
>>>>>>>>>> b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
>>>>>>>>>> @@ -832,7 +832,11 @@ public final class JAXRSUtils {
>>>>>>>>>>                                             OperationResourceInfo 
>>>>>>>>>> ori)
>>>>>>>>>>          throws IOException, WebApplicationException {
>>>>>>>>>>          InputStream is = message.getContent(InputStream.class);
>>>>>>>>>> -
>>>>>>>>>> +        if (is == null) {
>>>>>>>>>> +            //may use the jms transport so check the Reader;
>>>>>>>>>> +            Reader reader = message.getContent(Reader.class);
>>>>>>>>>> +            is = new ReaderInputStream(reader);
>>>>>>>>>> +        }
>>>>>>>>>>          if (parameter.getType() == ParameterType.REQUEST_BODY) {
>>>>>>>>>>              if (parameterClass == AsyncResponse.class) {
>>>>>>>>>> diff --git 
>>>>>>>>>> a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ReaderInputStream.java 
>>>>>>>>>> b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ReaderInputStream.java
>>>>>>>>>> new file mode 100644
>>>>>>>>>> index 0000000..c7b142e
>>>>>>>>>> --- /dev/null
>>>>>>>>>> +++ 
>>>>>>>>>> b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ReaderInputStream.java
>>>>>>>>>> @@ -0,0 +1,296 @@
>>>>>>>>>> +/**
>>>>>>>>>> + * Licensed to the Apache Software Foundation (ASF) under one
>>>>>>>>>> + * or more contributor license agreements. See the NOTICE file
>>>>>>>>>> + * distributed with this work for additional information
>>>>>>>>>> + * regarding copyright ownership. The ASF licenses this file
>>>>>>>>>> + * to you under the Apache License, Version 2.0 (the
>>>>>>>>>> + * "License"); you may not use this file except in compliance
>>>>>>>>>> + * with the License. You may obtain a copy of the License at
>>>>>>>>>> + *
>>>>>>>>>> + * http://www.apache.org/licenses/LICENSE-2.0
>>>>>>>>>> + *
>>>>>>>>>> + * Unless required by applicable law or agreed to in writing,
>>>>>>>>>> + * software distributed under the License is distributed on an
>>>>>>>>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>>>>>>> + * KIND, either express or implied. See the License for the
>>>>>>>>>> + * specific language governing permissions and limitations
>>>>>>>>>> + * under the License.
>>>>>>>>>> + */
>>>>>>>>>> +package org.apache.cxf.jaxrs.utils;
>>>>>>>>>> +
>>>>>>>>>> +import java.io.IOException;
>>>>>>>>>> +import java.io.InputStream;
>>>>>>>>>> +import java.io.Reader;
>>>>>>>>>> +import java.nio.ByteBuffer;
>>>>>>>>>> +import java.nio.CharBuffer;
>>>>>>>>>> +import java.nio.charset.Charset;
>>>>>>>>>> +import java.nio.charset.CharsetEncoder;
>>>>>>>>>> +import java.nio.charset.CoderResult;
>>>>>>>>>> +import java.nio.charset.CodingErrorAction;
>>>>>>>>>> +
>>>>>>>>>> +/**
>>>>>>>>>> + * {@link InputStream} implementation that reads a character 
>>>>>>>>>> stream from a {@link Reader}
>>>>>>>>>> + * and transforms it to a byte stream using a specified 
>>>>>>>>>> charset encoding. The stream
>>>>>>>>>> + * is transformed using a {@link CharsetEncoder} object, 
>>>>>>>>>> guaranteeing that all charset
>>>>>>>>>> + * encodings supported by the JRE are handled correctly. In 
>>>>>>>>>> particular for charsets such as
>>>>>>>>>> + * UTF-16, the implementation ensures that one and only one 
>>>>>>>>>> byte order marker
>>>>>>>>>> + * is produced.
>>>>>>>>>> + * <p>
>>>>>>>>>> + * Since in general it is not possible to predict the number 
>>>>>>>>>> of characters to be read from the
>>>>>>>>>> + * {@link Reader} to satisfy a read request on the {@link 
>>>>>>>>>> ReaderInputStream}, all reads from
>>>>>>>>>> + * the {@link Reader} are buffered. There is therefore no 
>>>>>>>>>> well defined correlation
>>>>>>>>>> + * between the current position of the {@link Reader} and 
>>>>>>>>>> that of the {@link ReaderInputStream}.
>>>>>>>>>> + * This also implies that in general there is no need to wrap 
>>>>>>>>>> the underlying {@link Reader}
>>>>>>>>>> + * in a {@link java.io.BufferedReader}.
>>>>>>>>>> + * <p>
>>>>>>>>>> + * {@link ReaderInputStream} implements the inverse 
>>>>>>>>>> transformation of {@link java.io.InputStreamReader};
>>>>>>>>>> + * in the following example, reading from <tt>in2</tt> would 
>>>>>>>>>> return the same byte
>>>>>>>>>> + * sequence as reading from <tt>in</tt> (provided that the 
>>>>>>>>>> initial byte sequence is legal
>>>>>>>>>> + * with respect to the charset encoding):
>>>>>>>>>> + * <pre>
>>>>>>>>>> + * InputStream in = ...
>>>>>>>>>> + * Charset cs = ...
>>>>>>>>>> + * InputStreamReader reader = new InputStreamReader(in, cs);
>>>>>>>>>> + * ReaderInputStream in2 = new ReaderInputStream(reader, 
>>>>>>>>>> cs);</pre>
>>>>>>>>>> + * {@link ReaderInputStream} implements the same 
>>>>>>>>>> transformation as {@link java.io.OutputStreamWriter},
>>>>>>>>>> + * except that the control flow is reversed: both classes 
>>>>>>>>>> transform a character stream
>>>>>>>>>> + * into a byte stream, but {@link java.io.OutputStreamWriter} 
>>>>>>>>>> pushes data to the underlying stream,
>>>>>>>>>> + * while {@link ReaderInputStream} pulls it from the 
>>>>>>>>>> underlying stream.
>>>>>>>>>> + * <p>
>>>>>>>>>> + * Note that while there are use cases where there is no 
>>>>>>>>>> alternative to using
>>>>>>>>>> + * this class, very often the need to use this class is an 
>>>>>>>>>> indication of a flaw
>>>>>>>>>> + * in the design of the code. This class is typically used in 
>>>>>>>>>> situations where an existing
>>>>>>>>>> + * API only accepts an {@link InputStream}, but where the 
>>>>>>>>>> most natural way to produce the data
>>>>>>>>>> + * is as a character stream, i.e. by providing a {@link 
>>>>>>>>>> Reader} instance. An example of a situation
>>>>>>>>>> + * where this problem may appear is when implementing the 
>>>>>>>>>> {@link javax.activation.DataSource}
>>>>>>>>>> + * interface from the Java Activation Framework.
>>>>>>>>>> + * <p>
>>>>>>>>>> + * Given the fact that the {@link Reader} class doesn't 
>>>>>>>>>> provide any way to predict whether the next
>>>>>>>>>> + * read operation will block or not, it is not possible to 
>>>>>>>>>> provide a meaningful
>>>>>>>>>> + * implementation of the {@link InputStream#available()} 
>>>>>>>>>> method. A call to this method
>>>>>>>>>> + * will always return 0. Also, this class doesn't support 
>>>>>>>>>> {@link InputStream#mark(int)}.
>>>>>>>>>> + * <p>
>>>>>>>>>> + * Instances of {@link ReaderInputStream} are not thread safe.
>>>>>>>>>> + *
>>>>>>>>>> + * @see org.apache.commons.io.output.WriterOutputStream
>>>>>>>>>> + *
>>>>>>>>>> + * @since 2.0
>>>>>>>>>> + */
>>>>>>>>>> +public class ReaderInputStream extends InputStream {
>>>>>>>>>> +    private static final int DEFAULT_BUFFER_SIZE = 1024;
>>>>>>>>>> +
>>>>>>>>>> +    private final Reader reader;
>>>>>>>>>> +    private final CharsetEncoder encoder;
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * CharBuffer used as input for the decoder. It should be 
>>>>>>>>>> reasonably
>>>>>>>>>> +     * large as we read data from the underlying Reader into 
>>>>>>>>>> this buffer.
>>>>>>>>>> +     */
>>>>>>>>>> +    private final CharBuffer encoderIn;
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * ByteBuffer used as output for the decoder. This buffer 
>>>>>>>>>> can be small
>>>>>>>>>> +     * as it is only used to transfer data from the decoder 
>>>>>>>>>> to the
>>>>>>>>>> +     * buffer provided by the caller.
>>>>>>>>>> +     */
>>>>>>>>>> +    private final ByteBuffer encoderOut;
>>>>>>>>>> +
>>>>>>>>>> +    private CoderResult lastCoderResult;
>>>>>>>>>> +    private boolean endOfInput;
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream}.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     * @param encoder the charset encoder
>>>>>>>>>> +     * @since 2.1
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader, CharsetEncoder 
>>>>>>>>>> encoder) {
>>>>>>>>>> +        this(reader, encoder, DEFAULT_BUFFER_SIZE);
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream}.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     * @param encoder the charset encoder
>>>>>>>>>> +     * @param bufferSize the size of the input buffer in 
>>>>>>>>>> number of characters
>>>>>>>>>> +     * @since 2.1
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader, CharsetEncoder 
>>>>>>>>>> encoder, int bufferSize) {
>>>>>>>>>> +        this.reader = reader;
>>>>>>>>>> +        this.encoder = encoder;
>>>>>>>>>> +        this.encoderIn = CharBuffer.allocate(bufferSize);
>>>>>>>>>> +        this.encoderIn.flip();
>>>>>>>>>> +        this.encoderOut = ByteBuffer.allocate(128);
>>>>>>>>>> +        this.encoderOut.flip();
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream}.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     * @param charset the charset encoding
>>>>>>>>>> +     * @param bufferSize the size of the input buffer in 
>>>>>>>>>> number of characters
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader, Charset charset, 
>>>>>>>>>> int bufferSize) {
>>>>>>>>>> +        this(reader,
>>>>>>>>>> +             charset.newEncoder()
>>>>>>>>>> +                    .onMalformedInput(CodingErrorAction.REPLACE)
>>>>>>>>>> + 
>>>>>>>>>>                    .onUnmappableCharacter(CodingErrorAction.REPLACE),
>>>>>>>>>> +             bufferSize);
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream} with a 
>>>>>>>>>> default input buffer size of
>>>>>>>>>> +     * 1024 characters.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     * @param charset the charset encoding
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader, Charset charset) {
>>>>>>>>>> +        this(reader, charset, DEFAULT_BUFFER_SIZE);
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream}.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     * @param charsetName the name of the charset encoding
>>>>>>>>>> +     * @param bufferSize the size of the input buffer in 
>>>>>>>>>> number of characters
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader, String 
>>>>>>>>>> charsetName, int bufferSize) {
>>>>>>>>>> +        this(reader, Charset.forName(charsetName), bufferSize);
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream} with a 
>>>>>>>>>> default input buffer size of
>>>>>>>>>> +     * 1024 characters.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     * @param charsetName the name of the charset encoding
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader, String charsetName) {
>>>>>>>>>> +        this(reader, charsetName, DEFAULT_BUFFER_SIZE);
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Construct a new {@link ReaderInputStream} that uses 
>>>>>>>>>> the default character encoding
>>>>>>>>>> +     * with a default input buffer size of 1024 characters.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param reader the target {@link Reader}
>>>>>>>>>> +     */
>>>>>>>>>> +    public ReaderInputStream(Reader reader) {
>>>>>>>>>> +        this(reader, Charset.defaultCharset());
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Fills the internal char buffer from the reader.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @throws IOException
>>>>>>>>>> +     *             If an I/O error occurs
>>>>>>>>>> +     */
>>>>>>>>>> +    private void fillBuffer() throws IOException {
>>>>>>>>>> +        if (!endOfInput && (lastCoderResult == null || 
>>>>>>>>>> lastCoderResult.isUnderflow())) {
>>>>>>>>>> +            encoderIn.compact();
>>>>>>>>>> +            int position = encoderIn.position();
>>>>>>>>>> +            // We don't use Reader#read(CharBuffer) here 
>>>>>>>>>> because it is more efficient
>>>>>>>>>> +            // to write directly to the underlying char array 
>>>>>>>>>> (the default implementation
>>>>>>>>>> +            // copies data to a temporary char array).
>>>>>>>>>> +            int c = reader.read(encoderIn.array(), position, 
>>>>>>>>>> encoderIn.remaining());
>>>>>>>>>> +            if (c == -1) {
>>>>>>>>>> +                endOfInput = true;
>>>>>>>>>> +            } else {
>>>>>>>>>> +                encoderIn.position(position + c);
>>>>>>>>>> +            }
>>>>>>>>>> +            encoderIn.flip();
>>>>>>>>>> +        }
>>>>>>>>>> +        encoderOut.compact();
>>>>>>>>>> +        lastCoderResult = encoder.encode(encoderIn, 
>>>>>>>>>> encoderOut, endOfInput);
>>>>>>>>>> +        encoderOut.flip();
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Read the specified number of bytes into an array.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param b the byte array to read into
>>>>>>>>>> +     * @param off the offset to start reading bytes into
>>>>>>>>>> +     * @param len the number of bytes to read
>>>>>>>>>> +     * @return the number of bytes read or <code>-1</code>
>>>>>>>>>> +     *         if the end of the stream has been reached
>>>>>>>>>> +     * @throws IOException if an I/O error occurs
>>>>>>>>>> +     */
>>>>>>>>>> +    @Override
>>>>>>>>>> +    public int read(byte[] b, int off, int len) throws 
>>>>>>>>>> IOException {
>>>>>>>>>> +        if (b == null) {
>>>>>>>>>> +            throw new NullPointerException("Byte array must 
>>>>>>>>>> not be null");
>>>>>>>>>> +        }
>>>>>>>>>> +        if (len < 0 || off < 0 || (off + len) > b.length) {
>>>>>>>>>> +            throw new IndexOutOfBoundsException("Array Size=" 
>>>>>>>>>> + b.length
>>>>>>>>>> +                    + ", offset=" + off + ", length=" + len);
>>>>>>>>>> +        }
>>>>>>>>>> +        int read = 0;
>>>>>>>>>> +        if (len == 0) {
>>>>>>>>>> +            return 0; // Always return 0 if len == 0
>>>>>>>>>> +        }
>>>>>>>>>> +        while (len > 0) {
>>>>>>>>>> +            if (encoderOut.hasRemaining()) {
>>>>>>>>>> +                int c = Math.min(encoderOut.remaining(), len);
>>>>>>>>>> +                encoderOut.get(b, off, c);
>>>>>>>>>> +                off += c;
>>>>>>>>>> +                len -= c;
>>>>>>>>>> +                read += c;
>>>>>>>>>> +            } else {
>>>>>>>>>> +                fillBuffer();
>>>>>>>>>> +                if (endOfInput && !encoderOut.hasRemaining()) {
>>>>>>>>>> +                    break;
>>>>>>>>>> +                }
>>>>>>>>>> +            }
>>>>>>>>>> +        }
>>>>>>>>>> +        return read == 0 && endOfInput ? -1 : read;
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Read the specified number of bytes into an array.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @param b the byte array to read into
>>>>>>>>>> +     * @return the number of bytes read or <code>-1</code>
>>>>>>>>>> +     *         if the end of the stream has been reached
>>>>>>>>>> +     * @throws IOException if an I/O error occurs
>>>>>>>>>> +     */
>>>>>>>>>> +    @Override
>>>>>>>>>> +    public int read(byte[] b) throws IOException {
>>>>>>>>>> +        return read(b, 0, b.length);
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Read a single byte.
>>>>>>>>>> +     *
>>>>>>>>>> +     * @return either the byte read or <code>-1</code> if the 
>>>>>>>>>> end of the stream
>>>>>>>>>> +     *         has been reached
>>>>>>>>>> +     * @throws IOException if an I/O error occurs
>>>>>>>>>> +     */
>>>>>>>>>> +    @Override
>>>>>>>>>> +    public int read() throws IOException {
>>>>>>>>>> +        for (;;) {
>>>>>>>>>> +            if (encoderOut.hasRemaining()) {
>>>>>>>>>> +                return encoderOut.get() & 0xFF;
>>>>>>>>>> +            } else {
>>>>>>>>>> +                fillBuffer();
>>>>>>>>>> +                if (endOfInput && !encoderOut.hasRemaining()) {
>>>>>>>>>> +                    return -1;
>>>>>>>>>> +                }
>>>>>>>>>> +            }
>>>>>>>>>> +        }
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +    /**
>>>>>>>>>> +     * Close the stream. This method will cause the 
>>>>>>>>>> underlying {@link Reader}
>>>>>>>>>> +     * to be closed.
>>>>>>>>>> +     * @throws IOException if an I/O error occurs
>>>>>>>>>> +     */
>>>>>>>>>> +    @Override
>>>>>>>>>> +    public void close() throws IOException {
>>>>>>>>>> +        reader.close();
>>>>>>>>>> +    }
>>>>>>>>>> +}
>>>>>>>>>> diff --git 
>>>>>>>>>> a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jms/JAXRSJmsTest.java 
>>>>>>>>>> b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jms/JAXRSJmsTest.java
>>>>>>>>>> index f77b5ed..b957f36 100644
>>>>>>>>>> --- 
>>>>>>>>>> a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jms/JAXRSJmsTest.java
>>>>>>>>>> +++ 
>>>>>>>>>> b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jms/JAXRSJmsTest.java
>>>>>>>>>> @@ -96,6 +96,25 @@ public class JAXRSJmsTest extends 
>>>>>>>>>> AbstractBusClientServerTestBase {
>>>>>>>>>>          assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> client.getResponse().getStatus());
>>>>>>>>>>          assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>>      }
>>>>>>>>>> +
>>>>>>>>>> +    @Test
>>>>>>>>>> +    public void testGetBookFromWebClientWithTextJMSMessage() 
>>>>>>>>>> throws Exception {
>>>>>>>>>> +        // setup the the client
>>>>>>>>>> +        String endpointAddressUrlEncoded = 
>>>>>>>>>> "jms:jndi:dynamicQueues/test.jmstransport.text"
>>>>>>>>>> +             + 
>>>>>>>>>> "?replyToName=dynamicQueues/test.jmstransport.response"
>>>>>>>>>> +             + 
>>>>>>>>>> "&jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
>>>>>>>>>> +             + "&jndiURL=tcp://localhost:" + JMS_PORT
>>>>>>>>>> +             + "&messageType=text";
>>>>>>>>>> +
>>>>>>>>>> +        WebClient client = 
>>>>>>>>>> WebClient.create(endpointAddressUrlEncoded);
>>>>>>>>>> + 
>>>>>>>>>>        WebClient.getConfig(client).getInInterceptors().add(new 
>>>>>>>>>> LoggingInInterceptor());
>>>>>>>>>> +        WebClient.getConfig(client).getRequestContext()
>>>>>>>>>> +            .put(org.apache.cxf.message.Message.REQUEST_URI, 
>>>>>>>>>> "/bookstore/books/123");
>>>>>>>>>> +
>>>>>>>>>> +        Book book = client.get(Book.class);
>>>>>>>>>> +        assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> client.getResponse().getStatus());
>>>>>>>>>> +        assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>> +    }
>>>>>>>>>>      @Test
>>>>>>>>>>      public void testPutBookOneWayWithWebClient() throws 
>>>>>>>>>> Exception {
>>>>>>>>>> @@ -130,6 +149,7 @@ public class JAXRSJmsTest extends 
>>>>>>>>>> AbstractBusClientServerTestBase {
>>>>>>>>>>          }
>>>>>>>>>>      }
>>>>>>>>>> +
>>>>>>>>>>      @Test
>>>>>>>>>>      public void testGetBookFromWebClientWithPath() throws 
>>>>>>>>>> Exception {
>>>>>>>>>>          // setup the the client
>>>>>>>>>> @@ -148,6 +168,25 @@ public class JAXRSJmsTest extends 
>>>>>>>>>> AbstractBusClientServerTestBase {
>>>>>>>>>>      }
>>>>>>>>>>      @Test
>>>>>>>>>> +    public void 
>>>>>>>>>> testGetBookFromWebClientWithPathWithTextJMSMessage() throws 
>>>>>>>>>> Exception {
>>>>>>>>>> +        // setup the the client
>>>>>>>>>> +        String endpointAddressUrlEncoded = 
>>>>>>>>>> "jms:jndi:dynamicQueues/test.jmstransport.text"
>>>>>>>>>> +             + 
>>>>>>>>>> "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
>>>>>>>>>> +             + 
>>>>>>>>>> "&replyToName=dynamicQueues/test.jmstransport.response"
>>>>>>>>>> +             + "&jndiURL=tcp://localhost:" + JMS_PORT
>>>>>>>>>> +             + "&jndiConnectionFactoryName=ConnectionFactory"
>>>>>>>>>> +             + "&messageType=text";
>>>>>>>>>> +
>>>>>>>>>> +        WebClient client = 
>>>>>>>>>> WebClient.create(endpointAddressUrlEncoded);
>>>>>>>>>> +        client.path("bookstore").path("books").path("123");
>>>>>>>>>> +
>>>>>>>>>> +        Book book = client.get(Book.class);
>>>>>>>>>> +        assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> client.getResponse().getStatus());
>>>>>>>>>> +        assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +
>>>>>>>>>> +    @Test
>>>>>>>>>>      public void testGetBookFromProxyClient() throws Exception {
>>>>>>>>>>          // setup the the client
>>>>>>>>>>          String endpointAddressUrlEncoded = 
>>>>>>>>>> "jms:jndi:dynamicQueues/test.jmstransport.text"
>>>>>>>>>> @@ -161,6 +200,22 @@ public class JAXRSJmsTest extends 
>>>>>>>>>> AbstractBusClientServerTestBase {
>>>>>>>>>>          assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> WebClient.client(client).getResponse().getStatus());
>>>>>>>>>>          assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>>      }
>>>>>>>>>> +
>>>>>>>>>> +    @Test
>>>>>>>>>> +    public void 
>>>>>>>>>> testGetBookFromProxyClientWithTextJMSMessage() throws Exception {
>>>>>>>>>> +        // setup the the client
>>>>>>>>>> +        String endpointAddressUrlEncoded = 
>>>>>>>>>> "jms:jndi:dynamicQueues/test.jmstransport.text"
>>>>>>>>>> +             + 
>>>>>>>>>> "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
>>>>>>>>>> +             + 
>>>>>>>>>> "&replyToName=dynamicQueues/test.jmstransport.response"
>>>>>>>>>> +             + "&jndiURL=tcp://localhost:" + JMS_PORT
>>>>>>>>>> +             + "&jndiConnectionFactoryName=ConnectionFactory"
>>>>>>>>>> +             + "&messageType=text";
>>>>>>>>>> +
>>>>>>>>>> +        JMSBookStore client = 
>>>>>>>>>> JAXRSClientFactory.create(endpointAddressUrlEncoded, 
>>>>>>>>>> JMSBookStore.class);
>>>>>>>>>> +        Book book = client.getBook("123");
>>>>>>>>>> +        assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> WebClient.client(client).getResponse().getStatus());
>>>>>>>>>> +        assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>> +    }
>>>>>>>>>>      @Test
>>>>>>>>>>      public void testGetBookFromSubresourceProxyClient() 
>>>>>>>>>> throws Exception {
>>>>>>>>>> @@ -177,6 +232,23 @@ public class JAXRSJmsTest extends 
>>>>>>>>>> AbstractBusClientServerTestBase {
>>>>>>>>>>          assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> WebClient.client(bookProxy).getResponse().getStatus());
>>>>>>>>>>          assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>>      }
>>>>>>>>>> +
>>>>>>>>>> +    @Test
>>>>>>>>>> +    public void 
>>>>>>>>>> testGetBookFromSubresourceProxyClientWithTextJMSMessage() 
>>>>>>>>>> throws Exception {
>>>>>>>>>> +        // setup the the client
>>>>>>>>>> +        String endpointAddressUrlEncoded = 
>>>>>>>>>> "jms:jndi:dynamicQueues/test.jmstransport.text"
>>>>>>>>>> +             + 
>>>>>>>>>> "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
>>>>>>>>>> +             + 
>>>>>>>>>> "&replyToName=dynamicQueues/test.jmstransport.response"
>>>>>>>>>> +             + "&jndiURL=tcp://localhost:" + JMS_PORT
>>>>>>>>>> +             + "&jndiConnectionFactoryName=ConnectionFactory"
>>>>>>>>>> +             + "&messageType=text";
>>>>>>>>>> +
>>>>>>>>>> +        JMSBookStore client = 
>>>>>>>>>> JAXRSClientFactory.create(endpointAddressUrlEncoded, 
>>>>>>>>>> JMSBookStore.class);
>>>>>>>>>> +        Book bookProxy = client.getBookSubResource("123");
>>>>>>>>>> +        Book book = bookProxy.retrieveState();
>>>>>>>>>> +        assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> WebClient.client(bookProxy).getResponse().getStatus());
>>>>>>>>>> +        assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>> +    }
>>>>>>>>>>      @Test
>>>>>>>>>>      public void testGetBookFromProxyClientWithQuery() throws 
>>>>>>>>>> Exception {
>>>>>>>>>> @@ -193,6 +265,24 @@ public class JAXRSJmsTest extends 
>>>>>>>>>> AbstractBusClientServerTestBase {
>>>>>>>>>>          assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>>      }
>>>>>>>>>> +
>>>>>>>>>> +    @Test
>>>>>>>>>> +    public void 
>>>>>>>>>> testGetBookFromProxyClientWithQueryWithTextJMSMessage() throws 
>>>>>>>>>> Exception {
>>>>>>>>>> +        // setup the the client
>>>>>>>>>> +        String endpointAddressUrlEncoded = 
>>>>>>>>>> "jms:jndi:dynamicQueues/test.jmstransport.text"
>>>>>>>>>> +             + 
>>>>>>>>>> "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
>>>>>>>>>> +             + 
>>>>>>>>>> "&replyToName=dynamicQueues/test.jmstransport.response"
>>>>>>>>>> +             + "&jndiURL=tcp://localhost:" + JMS_PORT
>>>>>>>>>> +             + "&jndiConnectionFactoryName=ConnectionFactory"
>>>>>>>>>> +             + "&messageType=text";
>>>>>>>>>> +
>>>>>>>>>> +        JMSBookStore client = 
>>>>>>>>>> JAXRSClientFactory.create(endpointAddressUrlEncoded, 
>>>>>>>>>> JMSBookStore.class);
>>>>>>>>>> +        Book book = client.getBookByURLQuery(new String[] 
>>>>>>>>>> {"1", "2", "3"});
>>>>>>>>>> +        assertEquals("Get a wrong response code.", 200, 
>>>>>>>>>> WebClient.client(client).getResponse().getStatus());
>>>>>>>>>> +        assertEquals("Get a wrong book id.", 123, book.getId());
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>> +
>>>>>>>>>>      @Test
>>>>>>>>>>      public void testGetBook() throws Exception {
>>>>>>>>>>          Context ctx = getContext();
>>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>>> -- 
>>>>> Sergey Beryozkin
>>>>>
>>>>> Talend Community Coders
>>>>> http://coders.talend.com/
>>>>
> 


Mime
View raw message