• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

smartsheet / smartsheet-java-sdk / #60

24 Oct 2025 09:43AM UTC coverage: 60.156% (+0.4%) from 59.737%
#60

push

github

web-flow
Add Wiremock integration tests and update dependencies (#145)

* Add Wiremock integration tests and update dependencies

* Update test method names

* Bump version to 3.9.0 and address comments for the wiremock integration tests

* Refactor Wiremock integration tests for user resources to improve query parameter handling and update endpoint paths

* Fix imports

* Fix checkstyle errors

* Move wiremock tests to sdktest

* Remove redundant Wiremock tests from UserResourcesIT

* Remove unused imports from UserResourcesIT

* Revert UserResourcesIT

* Fix changelog

* Add copyright to WiremockTest

* Update wiremock base uri port

* Rename WiremockTest to UserResourcesContractTests for clarity

* Change WireMock default port

4392 of 7301 relevant lines covered (60.16%)

0.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.22
/src/main/java/com/smartsheet/api/internal/util/StreamUtil.java
1
/*
2
 * Copyright (C) 2025 Smartsheet
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package com.smartsheet.api.internal.util;
18

19
import org.apache.commons.codec.binary.Hex;
20

21
import java.io.ByteArrayInputStream;
22
import java.io.ByteArrayOutputStream;
23
import java.io.IOException;
24
import java.io.InputStream;
25
import java.io.OutputStream;
26
import java.nio.charset.StandardCharsets;
27

28
/**
29
 * a collection of Stream-oriented utility methods
30
 */
31
public class StreamUtil {
32
    private StreamUtil() {
33
        // Empty private constructor since every method in this class is static
34
    }
35

36
    public static final int ONE_MB = 1 << 20;
37
    public static final int ONE_KB = 1 << 10;
38
    public static final int TEN_KB = 10 * ONE_KB;
39

40
    /**
41
     * read all bytes from an InputStream; doesn't close input-stream
42
     *
43
     * @param source the input stream to consume
44
     * @return the bytes read from 'is'
45
     * @throws IOException if anything goes wrong reading from 'is'
46
     */
47
    public static byte[] readBytesFromStream(InputStream source) throws IOException {
48
        return readBytesFromStream(source, ONE_MB);
1✔
49
    }
50

51
    /**
52
     * read all bytes from an InputStream with the specified buffer size; doesn't close input-stream
53
     *
54
     * @param source     the input stream to consume
55
     * @param bufferSize the buffer size to use when reading the stream
56
     * @return the bytes read from 'is'
57
     * @throws IOException if anything goes wrong reading from 'is'
58
     */
59
    public static byte[] readBytesFromStream(InputStream source, int bufferSize) throws IOException {
60
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1✔
61
        copyContentIntoOutputStream(source, buffer, bufferSize, true);
1✔
62
        return buffer.toByteArray();
1✔
63
    }
64

65
    /**
66
     * the real work-horse behind most of these methods
67
     *
68
     * @param source     the source InputStream from which to read the data (not closed when done)
69
     * @param target     the target OutputStream to which to write the data (not closed when done)
70
     * @param bufferSize the size of the transfer buffer to use
71
     * @param readToEOF  if we should read to end-of-file of the source (true) or just 1 buffer's worth (false)
72
     */
73
    public static long copyContentIntoOutputStream(
74
            InputStream source,
75
            OutputStream target,
76
            int bufferSize,
77
            boolean readToEOF
78
    ) throws IOException {
79
        // at least a 1k buffer
80
        byte[] tempBuf = new byte[Math.max(ONE_KB, bufferSize)];
1✔
81
        long bytesWritten = 0;
1✔
82
        while (true) {
83
            int bytesRead = source.read(tempBuf);
1✔
84
            if (bytesRead < 0) {
1✔
85
                break;
1✔
86
            }
87
            target.write(tempBuf, 0, bytesRead);
1✔
88
            bytesWritten += bytesRead;
1✔
89
            if (!readToEOF) {
1✔
90
                // prevents us from reading more than 1 buffer worth
91
                break;
1✔
92
            }
93

94
        }
1✔
95
        return bytesWritten;
1✔
96
    }
97

98
    /**
99
     * used when you want to clone a InputStream's content and still have it appear "rewound" to the stream beginning
100
     *
101
     * @param source       the stream around the contents we want to clone
102
     * @param readbackSize the farthest we should read a resetable stream before giving up
103
     * @param target       an output stream into which we place a copy of the content read from source
104
     * @return the source if it was resetable; a new stream rewound around the source data otherwise
105
     * @throws IOException if any issues occur with the reading of bytes from the source stream
106
     */
107
    public static InputStream cloneContent(InputStream source, int readbackSize, ByteArrayOutputStream target) throws IOException {
108
        if (source == null) {
1✔
109
            return null;
1✔
110
        }
111
        // if the source supports mark/reset then we read and then reset up to the read-back size
112
        if (source.markSupported()) {
1✔
113
            // at least 10 KB (minimal waste, handles those -1 ContentLength cases)
114
            readbackSize = Math.max(TEN_KB, readbackSize);
1✔
115
            source.mark(readbackSize);
1✔
116
            copyContentIntoOutputStream(source, target, readbackSize, false);
1✔
117
            source.reset();
1✔
118
            return source;
1✔
119
        } else {
120
            copyContentIntoOutputStream(source, target, ONE_MB, true);
1✔
121
            byte[] fullContentBytes = target.toByteArray();
1✔
122
            // if we can't reset the source we need to create a replacement stream so others can read the content
123
            return new ByteArrayInputStream(fullContentBytes);
1✔
124
        }
125
    }
126

127
    /**
128
     * a convenience method to reduce all the casting of HttpEntity.getContentLength() to int
129
     */
130
    public static InputStream cloneContent(InputStream source, long readbackSize, ByteArrayOutputStream target) throws IOException {
131
        return cloneContent(source, (int) Math.min((long) Integer.MAX_VALUE, readbackSize), target);
×
132
    }
133

134
    /**
135
     * generate a String of UTF-8 characters (or hex-digits if byteStream isn't UTF-8 chars) from byteStream,
136
     * truncating to maxLen (with "..." added if the result is truncated)
137
     *
138
     * @param byteStream the source of bytes to be converted to a UTF-8 String
139
     * @param maxLen     the point at which to truncate the string (-1 means don't truncate) in which case "..." is appended
140
     * @return the String read from the stream
141
     */
142
    public static String toUtf8StringOrHex(ByteArrayOutputStream byteStream, int maxLen) {
143
        if (maxLen == -1) {
1✔
144
            maxLen = Integer.MAX_VALUE;
1✔
145
        }
146

147
        String result;
148
        try {
149
            result = byteStream.toString(StandardCharsets.UTF_8);
1✔
150
        } catch (Exception notUtf8) {
1✔
151
            result = Hex.encodeHexString(byteStream.toByteArray());
1✔
152
        }
1✔
153

154
        final int resultLen = result != null ? result.length() : 0;
1✔
155
        final String suffix = resultLen > maxLen ? "..." : "";
1✔
156
        return resultLen == 0 ? "" : result.substring(0, Math.min(resultLen, maxLen)) + suffix;
1✔
157
    }
158
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc