mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-23 06:29:10 +00:00
Refactor JettyDataBuffer with new JettyVirtualDataBuffer
This commits simplifies the Jetty buffer support by consolidating the shared logic and delegating operations to the parent class thanks to the new `JettyVirtualDataBuffer`. Signed-off-by: Istvan Verhas <vi@mocker.guru>
This commit is contained in:
committed by
Brian Clozel
parent
17e0daf8a1
commit
752193fca9
+20
-250
@@ -17,303 +17,73 @@
|
||||
package org.springframework.core.io.buffer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.IntPredicate;
|
||||
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of the {@code DataBuffer} interface that can wrap a Jetty
|
||||
* {@link Content.Chunk}. Typically constructed with {@link JettyDataBufferFactory}.
|
||||
* Implementation of the {@code DataBuffer} interface that can wrap a Jetty {@link Content.Chunk}. Typically constructed
|
||||
* with {@link JettyDataBufferFactory}.
|
||||
*
|
||||
* @author Greg Wilkins
|
||||
* @author Lachlan Roberts
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.2
|
||||
*/
|
||||
public final class JettyDataBuffer implements PooledDataBuffer {
|
||||
public final class JettyDataBuffer extends JettyVirtualDataBuffer {
|
||||
|
||||
private final DefaultDataBuffer delegate;
|
||||
private final Content.Chunk chunk;
|
||||
|
||||
private final Content.@Nullable Chunk chunk;
|
||||
JettyDataBuffer(JettyDataBufferFactory bufferFactory, DataBuffer delegate, Content.Chunk chunk) {
|
||||
super(bufferFactory, delegate);
|
||||
|
||||
private final JettyDataBufferFactory bufferFactory;
|
||||
|
||||
private final AtomicInteger refCount = new AtomicInteger(1);
|
||||
|
||||
|
||||
JettyDataBuffer(JettyDataBufferFactory bufferFactory, DefaultDataBuffer delegate, Content.Chunk chunk) {
|
||||
Assert.notNull(bufferFactory, "BufferFactory must not be null");
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
Assert.notNull(chunk, "Chunk must not be null");
|
||||
|
||||
this.bufferFactory = bufferFactory;
|
||||
this.delegate = delegate;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
JettyDataBuffer(JettyDataBufferFactory bufferFactory, DefaultDataBuffer delegate) {
|
||||
Assert.notNull(bufferFactory, "BufferFactory must not be null");
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
|
||||
this.bufferFactory = bufferFactory;
|
||||
this.delegate = delegate;
|
||||
this.chunk = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAllocated() {
|
||||
return this.refCount.get() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledDataBuffer retain() {
|
||||
int result = this.refCount.updateAndGet(c -> (c != 0 ? c + 1 : 0));
|
||||
if (result != 0 && this.chunk != null) {
|
||||
int result = incrementRefCount();
|
||||
if (result != 0) {
|
||||
this.chunk.retain();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledDataBuffer touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
int result = this.refCount.updateAndGet(c -> {
|
||||
if (c != 0) {
|
||||
return c - 1;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("JettyDataBuffer already released: " + this);
|
||||
}
|
||||
});
|
||||
if (this.chunk != null) {
|
||||
return this.chunk.release();
|
||||
}
|
||||
else {
|
||||
return (result == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBufferFactory factory() {
|
||||
return this.bufferFactory;
|
||||
}
|
||||
|
||||
|
||||
// delegation
|
||||
|
||||
@Override
|
||||
public int indexOf(IntPredicate predicate, int fromIndex) {
|
||||
return this.delegate.indexOf(predicate, fromIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(IntPredicate predicate, int fromIndex) {
|
||||
return this.delegate.lastIndexOf(predicate, fromIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readableByteCount() {
|
||||
return this.delegate.readableByteCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writableByteCount() {
|
||||
return this.delegate.writableByteCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int capacity() {
|
||||
return this.delegate.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public DataBuffer capacity(int capacity) {
|
||||
this.delegate.capacity(capacity);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer ensureWritable(int capacity) {
|
||||
this.delegate.ensureWritable(capacity);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readPosition() {
|
||||
return this.delegate.readPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer readPosition(int readPosition) {
|
||||
this.delegate.readPosition(readPosition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writePosition() {
|
||||
return this.delegate.writePosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer writePosition(int writePosition) {
|
||||
this.delegate.writePosition(writePosition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(int index) {
|
||||
return this.delegate.getByte(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte read() {
|
||||
return this.delegate.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer read(byte[] destination) {
|
||||
this.delegate.read(destination);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer read(byte[] destination, int offset, int length) {
|
||||
this.delegate.read(destination, offset, length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(byte b) {
|
||||
this.delegate.write(b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(byte[] source) {
|
||||
this.delegate.write(source);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(byte[] source, int offset, int length) {
|
||||
this.delegate.write(source, offset, length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(DataBuffer... buffers) {
|
||||
this.delegate.write(buffers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(ByteBuffer... buffers) {
|
||||
this.delegate.write(buffers);
|
||||
return this;
|
||||
decrementRefCount();
|
||||
return this.chunk.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public DataBuffer slice(int index, int length) {
|
||||
DefaultDataBuffer delegateSlice = this.delegate.slice(index, length);
|
||||
if (this.chunk != null) {
|
||||
this.chunk.retain();
|
||||
return new JettyDataBuffer(this.bufferFactory, delegateSlice, this.chunk);
|
||||
}
|
||||
else {
|
||||
return new JettyDataBuffer(this.bufferFactory, delegateSlice);
|
||||
}
|
||||
DataBuffer delegateSlice = super.slice(index, length);
|
||||
this.chunk.retain();
|
||||
return new JettyDataBuffer(this.bufferFactory, delegateSlice, this.chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer split(int index) {
|
||||
DefaultDataBuffer delegateSplit = this.delegate.split(index);
|
||||
if (this.chunk != null) {
|
||||
this.chunk.retain();
|
||||
return new JettyDataBuffer(this.bufferFactory, delegateSplit, this.chunk);
|
||||
}
|
||||
else {
|
||||
return new JettyDataBuffer(this.bufferFactory, delegateSplit);
|
||||
}
|
||||
DataBuffer delegateSplit = super.split(index);
|
||||
this.chunk.retain();
|
||||
return new JettyDataBuffer(this.bufferFactory, delegateSplit, this.chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public ByteBuffer asByteBuffer() {
|
||||
return this.delegate.asByteBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public ByteBuffer asByteBuffer(int index, int length) {
|
||||
return this.delegate.asByteBuffer(index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0.5")
|
||||
public ByteBuffer toByteBuffer(int index, int length) {
|
||||
return this.delegate.toByteBuffer(index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toByteBuffer(int srcPos, ByteBuffer dest, int destPos, int length) {
|
||||
this.delegate.toByteBuffer(srcPos, dest, destPos, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferIterator readableByteBuffers() {
|
||||
ByteBufferIterator delegateIterator = this.delegate.readableByteBuffers();
|
||||
if (this.chunk != null) {
|
||||
return new JettyByteBufferIterator(delegateIterator, this.chunk);
|
||||
}
|
||||
else {
|
||||
return delegateIterator;
|
||||
}
|
||||
ByteBufferIterator delegateIterator = super.readableByteBuffers();
|
||||
return new JettyByteBufferIterator(delegateIterator, this.chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferIterator writableByteBuffers() {
|
||||
ByteBufferIterator delegateIterator = this.delegate.writableByteBuffers();
|
||||
if (this.chunk != null) {
|
||||
return new JettyByteBufferIterator(delegateIterator, this.chunk);
|
||||
}
|
||||
else {
|
||||
return delegateIterator;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(int index, int length, Charset charset) {
|
||||
return this.delegate.toString(index, length, charset);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
return (this == other || (other instanceof JettyDataBuffer otherBuffer &&
|
||||
this.delegate.equals(otherBuffer.delegate)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("JettyDataBuffer (r: %d, w: %d, c: %d)",
|
||||
readPosition(), writePosition(), capacity());
|
||||
ByteBufferIterator delegateIterator = super.writableByteBuffers();
|
||||
return new JettyByteBufferIterator(delegateIterator, this.chunk);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-10
@@ -66,27 +66,27 @@ public class JettyDataBufferFactory implements DataBufferFactory {
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public JettyDataBuffer allocateBuffer() {
|
||||
public DataBuffer allocateBuffer() {
|
||||
DefaultDataBuffer delegate = this.delegate.allocateBuffer();
|
||||
return new JettyDataBuffer(this, delegate);
|
||||
return new JettyVirtualDataBuffer(this, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JettyDataBuffer allocateBuffer(int initialCapacity) {
|
||||
public DataBuffer allocateBuffer(int initialCapacity) {
|
||||
DefaultDataBuffer delegate = this.delegate.allocateBuffer(initialCapacity);
|
||||
return new JettyDataBuffer(this, delegate);
|
||||
return new JettyVirtualDataBuffer(this, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JettyDataBuffer wrap(ByteBuffer byteBuffer) {
|
||||
public DataBuffer wrap(ByteBuffer byteBuffer) {
|
||||
DefaultDataBuffer delegate = this.delegate.wrap(byteBuffer);
|
||||
return new JettyDataBuffer(this, delegate);
|
||||
return new JettyVirtualDataBuffer(this, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JettyDataBuffer wrap(byte[] bytes) {
|
||||
public DataBuffer wrap(byte[] bytes) {
|
||||
DefaultDataBuffer delegate = this.delegate.wrap(bytes);
|
||||
return new JettyDataBuffer(this, delegate);
|
||||
return new JettyVirtualDataBuffer(this, delegate);
|
||||
}
|
||||
|
||||
public JettyDataBuffer wrap(Content.Chunk chunk) {
|
||||
@@ -96,9 +96,9 @@ public class JettyDataBufferFactory implements DataBufferFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JettyDataBuffer join(List<? extends DataBuffer> dataBuffers) {
|
||||
public DataBuffer join(List<? extends DataBuffer> dataBuffers) {
|
||||
DefaultDataBuffer delegate = this.delegate.join(dataBuffers);
|
||||
return new JettyDataBuffer(this, delegate);
|
||||
return new JettyVirtualDataBuffer(this, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* https://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.springframework.core.io.buffer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.IntPredicate;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of the {@code DataBuffer} interface that can wrap another {@link DataBuffer}.
|
||||
* Typically constructed with {@link JettyDataBufferFactory}.
|
||||
* @author Istvan Verhas
|
||||
*/
|
||||
class JettyVirtualDataBuffer implements PooledDataBuffer {
|
||||
|
||||
final JettyDataBufferFactory bufferFactory;
|
||||
private final DataBuffer delegate;
|
||||
private final AtomicInteger refCount = new AtomicInteger(1);
|
||||
|
||||
JettyVirtualDataBuffer(JettyDataBufferFactory bufferFactory, DataBuffer delegate) {
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
|
||||
this.delegate = delegate;
|
||||
this.bufferFactory = bufferFactory;
|
||||
}
|
||||
|
||||
// delegation
|
||||
@Override
|
||||
public boolean isAllocated() {
|
||||
return this.refCount.get() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledDataBuffer retain() {
|
||||
incrementRefCount();
|
||||
return this;
|
||||
}
|
||||
|
||||
int incrementRefCount() {
|
||||
return this.refCount.updateAndGet(c -> (c != 0 ? c + 1 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledDataBuffer touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
int result = decrementRefCount();
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
int decrementRefCount() {
|
||||
return this.refCount.updateAndGet(c -> {
|
||||
if (c != 0) {
|
||||
return c - 1;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("JettyDataBuffer already released: " + this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBufferFactory factory() {
|
||||
return this.bufferFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(IntPredicate predicate, int fromIndex) {
|
||||
return this.delegate.indexOf(predicate, fromIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(IntPredicate predicate, int fromIndex) {
|
||||
return this.delegate.lastIndexOf(predicate, fromIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readableByteCount() {
|
||||
return this.delegate.readableByteCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writableByteCount() {
|
||||
return this.delegate.writableByteCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int capacity() {
|
||||
return this.delegate.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public DataBuffer capacity(int capacity) {
|
||||
this.delegate.capacity(capacity);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer ensureWritable(int capacity) {
|
||||
this.delegate.ensureWritable(capacity);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readPosition() {
|
||||
return this.delegate.readPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer readPosition(int readPosition) {
|
||||
this.delegate.readPosition(readPosition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writePosition() {
|
||||
return this.delegate.writePosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer writePosition(int writePosition) {
|
||||
this.delegate.writePosition(writePosition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(int index) {
|
||||
return this.delegate.getByte(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte read() {
|
||||
return this.delegate.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer read(byte[] destination) {
|
||||
this.delegate.read(destination);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer read(byte[] destination, int offset, int length) {
|
||||
this.delegate.read(destination, offset, length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(byte b) {
|
||||
this.delegate.write(b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(byte[] source) {
|
||||
this.delegate.write(source);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(byte[] source, int offset, int length) {
|
||||
this.delegate.write(source, offset, length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(DataBuffer... buffers) {
|
||||
this.delegate.write(buffers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer write(ByteBuffer... buffers) {
|
||||
this.delegate.write(buffers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public DataBuffer slice(int index, int length) {
|
||||
DataBuffer delegateSlice = this.delegate.slice(index, length);
|
||||
return new JettyVirtualDataBuffer(this.bufferFactory, delegateSlice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer split(int index) {
|
||||
DataBuffer delegateSplit = this.delegate.split(index);
|
||||
return new JettyVirtualDataBuffer(this.bufferFactory, delegateSplit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public ByteBuffer asByteBuffer() {
|
||||
return this.delegate.asByteBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0")
|
||||
public ByteBuffer asByteBuffer(int index, int length) {
|
||||
return this.delegate.asByteBuffer(index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.0.5")
|
||||
public ByteBuffer toByteBuffer(int index, int length) {
|
||||
return this.delegate.toByteBuffer(index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toByteBuffer(int srcPos, ByteBuffer dest, int destPos, int length) {
|
||||
this.delegate.toByteBuffer(srcPos, dest, destPos, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferIterator readableByteBuffers() {
|
||||
return this.delegate.readableByteBuffers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferIterator writableByteBuffers() {
|
||||
return this.delegate.writableByteBuffers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(int index, int length, Charset charset) {
|
||||
return this.delegate.toString(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
return (this == other || (other instanceof JettyVirtualDataBuffer otherBuffer &&
|
||||
this.delegate.equals(otherBuffer.delegate)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("JettyDataBuffer (r: %d, w: %d, c: %d)",
|
||||
readPosition(), writePosition(), capacity());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user