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

smartsheet / smartsheet-java-sdk / #66

26 Jun 2026 09:41AM UTC coverage: 59.997% (-0.006%) from 60.003%
#66

push

github

web-flow
Prepare for release v4.1.0 (#180)

4510 of 7517 relevant lines covered (60.0%)

0.6 hits per line

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

43.24
/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.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;
18

19
import com.smartsheet.api.AuthorizationException;
20
import com.smartsheet.api.InvalidRequestException;
21
import com.smartsheet.api.ReportResources;
22
import com.smartsheet.api.ResourceNotFoundException;
23
import com.smartsheet.api.ServiceUnavailableException;
24
import com.smartsheet.api.SmartsheetException;
25
import com.smartsheet.api.internal.http.HttpEntity;
26
import com.smartsheet.api.internal.http.HttpMethod;
27
import com.smartsheet.api.internal.http.HttpRequest;
28
import com.smartsheet.api.internal.http.HttpResponse;
29
import com.smartsheet.api.internal.json.JSONSerializerException;
30
import com.smartsheet.api.internal.util.QueryUtil;
31
import com.smartsheet.api.models.CreateReportRequest;
32
import com.smartsheet.api.models.CreateReportResult;
33
import com.smartsheet.api.models.PagedResult;
34
import com.smartsheet.api.models.PaginationParameters;
35
import com.smartsheet.api.models.Report;
36
import com.smartsheet.api.models.ReportColumn;
37
import com.smartsheet.api.models.ReportDefinition;
38
import com.smartsheet.api.models.ReportPublish;
39
import com.smartsheet.api.models.Result;
40
import com.smartsheet.api.models.ReportScopeInclusion;
41
import com.smartsheet.api.models.SheetEmail;
42
import com.smartsheet.api.models.ReportPathNode;
43
import com.smartsheet.api.internal.util.Util;
44
import com.smartsheet.api.models.enums.ReportInclusion;
45

46
import java.io.ByteArrayInputStream;
47
import java.io.ByteArrayOutputStream;
48
import java.io.OutputStream;
49
import java.text.SimpleDateFormat;
50
import java.util.Date;
51
import java.util.EnumSet;
52
import java.util.HashMap;
53
import java.util.Map;
54
import java.util.List;
55

56
/**
57
 * This is the implementation of the ReportResources.
58
 * <p>
59
 * Thread Safety: This class is thread safe because it is immutable and its base class is thread safe.
60
 */
61

62
public class ReportResourcesImpl extends AbstractResources implements ReportResources {
63

64
    private static final String JSON_CONTENT_TYPE = "application/json";
65
    private static final String REPORTS_PATH = "reports/";
66
    private static final String REPORTS = "reports";
67

68
    /**
69
     * Constructor.
70
     * <p>
71
     * Parameters: - smartsheet : the SmartsheetImpl
72
     * <p>
73
     * Exceptions: - IllegalArgumentException : if any argument is null
74
     *
75
     * @param smartsheet the smartsheet
76
     */
77
    public ReportResourcesImpl(SmartsheetImpl smartsheet) {
78
        super(smartsheet);
1✔
79
    }
1✔
80

81
    /**
82
     * Get a report.
83
     * <p>
84
     * It mirrors to the following Smartsheet REST API method: GET /reports/{id}
85
     * <p>
86
     * Exceptions:
87
     * InvalidRequestException : if there is any problem with the REST API request
88
     * AuthorizationException : if there is any problem with the REST API authorization(access token)
89
     * ResourceNotFoundException : if the resource can not be found
90
     * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
91
     * SmartsheetRestException : if there is any other REST API related error occurred during the operation
92
     * SmartsheetException : if there is any other error occurred during the operation
93
     *
94
     * @param reportId the folder id
95
     * @param includes the optional objects to include in response
96
     * @param pageSize Number of rows per page
97
     * @param page     page number to return
98
     * @return the report (note that if there is no such resource, this method will throw ResourceNotFoundException
99
     * rather than returning null)
100
     * @throws SmartsheetException the smartsheet exception
101
     */
102
    public Report getReport(long reportId, EnumSet<ReportInclusion> includes, Integer pageSize, Integer page) throws SmartsheetException {
103
        return this.getReport(reportId, includes, pageSize, page, null);
1✔
104
    }
105

106
    /**
107
     * Get a report.
108
     * <p>
109
     * It mirrors to the following Smartsheet REST API method: GET /reports/{id}
110
     * <p>
111
     * Exceptions:
112
     * InvalidRequestException : if there is any problem with the REST API request
113
     * AuthorizationException : if there is any problem with the REST API authorization(access token)
114
     * ResourceNotFoundException : if the resource can not be found
115
     * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
116
     * SmartsheetRestException : if there is any other REST API related error occurred during the operation
117
     * SmartsheetException : if there is any other error occurred during the operation
118
     *
119
     * @param reportId the folder id
120
     * @param includes the optional objects to include in response
121
     * @param pageSize Number of rows per page
122
     * @param page     page number to return
123
     * @param level    compatibility level
124
     * @return the report (note that if there is no such resource, this method will throw ResourceNotFoundException
125
     * rather than returning null)
126
     * @throws SmartsheetException the smartsheet exception
127
     */
128
    public Report getReport(
129
            long reportId,
130
            EnumSet<ReportInclusion> includes,
131
            Integer pageSize,
132
            Integer page,
133
            Integer level
134
    ) throws SmartsheetException {
135
        String path = REPORTS_PATH + reportId;
1✔
136
        Map<String, Object> parameters = new HashMap<>();
1✔
137

138
        parameters.put("include", QueryUtil.generateCommaSeparatedList(includes));
1✔
139
        if (pageSize != null) {
1✔
140
            parameters.put("pageSize", pageSize.toString());
1✔
141
        }
142

143
        if (page != null) {
1✔
144
            parameters.put("page", page.toString());
1✔
145
        }
146

147
        if (level != null) {
1✔
148
            parameters.put("level", level);
×
149
        }
150

151
        path += QueryUtil.generateUrl(null, parameters);
1✔
152
        return this.getResource(path, Report.class);
1✔
153
    }
154

155
    /**
156
     * Sends a report as a PDF attachment via email to the designated recipients.
157
     * <p>
158
     * It mirrors to the following Smartsheet REST API method: POST /reports/{id}/emails
159
     * <p>
160
     * Exceptions:
161
     * InvalidRequestException : if there is any problem with the REST API request
162
     * AuthorizationException : if there is any problem with the REST API authorization(access token)
163
     * ResourceNotFoundException : if the resource can not be found
164
     * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
165
     * SmartsheetRestException : if there is any other REST API related error occurred during the operation
166
     * SmartsheetException : if there is any other error occurred during the operation
167
     *
168
     * @param reportId the report id
169
     * @param email    the recipient email
170
     * @throws SmartsheetException the smartsheet exception
171
     */
172
    public void sendReport(long reportId, SheetEmail email) throws SmartsheetException {
173
        this.createResource(REPORTS_PATH + reportId + "/emails", SheetEmail.class, email);
1✔
174
    }
1✔
175

176
    /**
177
     * List all reports.
178
     * <p>
179
     * It mirrors to the following Smartsheet REST API method: GET /reports
180
     * <p>
181
     * Exceptions:
182
     * - InvalidRequestException : if there is any problem with the REST API request
183
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
184
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
185
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
186
     * - SmartsheetException : if there is any other error occurred during the operation
187
     *
188
     * @param pagination pagination parameters for paging result
189
     * @return all sheets (note that empty list will be returned if there is none)
190
     * @throws SmartsheetException the smartsheet exception
191
     */
192
    public PagedResult<Report> listReports(PaginationParameters pagination) throws SmartsheetException {
193
        return this.listReports(pagination, null);
×
194
    }
195

196
    /**
197
     * List all reports.
198
     */
199
    public PagedResult<Report> listReports(PaginationParameters pagination, Date modifiedSince) throws SmartsheetException {
200
        String path = REPORTS;
1✔
201

202
        Map<String, Object> parameters = new HashMap<>();
1✔
203
        if (pagination != null) {
1✔
204
            parameters = pagination.toHashMap();
1✔
205
        }
206
        if (modifiedSince != null) {
1✔
207
            String isoDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(modifiedSince);
×
208
            parameters.put("modifiedSince", isoDate);
×
209
        }
210

211
        path += QueryUtil.generateUrl(null, parameters);
1✔
212
        return this.listResourcesWithWrapper(path, Report.class);
1✔
213
    }
214

215
    /**
216
     * Get a Report as an Excel file.
217
     * <p>
218
     * It mirrors to the following Smartsheet REST API method: GET /reports/{id} with "application/vnd.ms-excel" Accept
219
     * HTTP header
220
     * <p>
221
     * Exceptions:
222
     * IllegalArgumentException : if outputStream is null
223
     * InvalidRequestException : if there is any problem with the REST API request
224
     * AuthorizationException : if there is any problem with the REST API authorization(access token)
225
     * ResourceNotFoundException : if the resource can not be found
226
     * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
227
     * SmartsheetRestException : if there is any other REST API related error occurred during the operation
228
     * SmartsheetException : if there is any other error occurred during the operation
229
     *
230
     * @param id           the id
231
     * @param outputStream the OutputStream to which the Excel file will be written
232
     * @throws SmartsheetException the smartsheet exception
233
     */
234
    public void getReportAsExcel(long id, OutputStream outputStream) throws SmartsheetException {
235
        getResourceAsFile(REPORTS_PATH + id, "application/vnd.ms-excel", outputStream);
1✔
236
    }
1✔
237

238
    /**
239
     * Get a Report as a csv file.
240
     * <p>
241
     * It mirrors to the following Smartsheet REST API method: GET /reports/{id} with "text/csv" Accept
242
     * HTTP header
243
     * <p>
244
     * Exceptions:
245
     * IllegalArgumentException : if outputStream is null
246
     * InvalidRequestException : if there is any problem with the REST API request
247
     * AuthorizationException : if there is any problem with the REST API authorization(access token)
248
     * ResourceNotFoundException : if the resource can not be found
249
     * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
250
     * SmartsheetRestException : if there is any other REST API related error occurred during the operation
251
     * SmartsheetException : if there is any other error occurred during the operation
252
     *
253
     * @param id           the id
254
     * @param outputStream the OutputStream to which the Excel file will be written
255
     * @throws SmartsheetException the smartsheet exception
256
     */
257
    public void getReportAsCsv(long id, OutputStream outputStream) throws SmartsheetException {
258
        getResourceAsFile(REPORTS_PATH + id, "text/csv", outputStream);
×
259
    }
×
260

261
    /**
262
     * Get the publish status of a report.
263
     * <p>
264
     * It mirrors to the following Smartsheet REST API method: GET /reports/{id}/publish
265
     * <p>
266
     * Exceptions:
267
     * InvalidRequestException : if there is any problem with the REST API request
268
     * AuthorizationException : if there is any problem with the REST API authorization(access token)
269
     * ResourceNotFoundException : if the resource can not be found
270
     * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
271
     * SmartsheetRestException : if there is any other REST API related error occurred during the operation
272
     * SmartsheetException : if there is any other error occurred during the operation
273
     *
274
     * @param id the ID of the report
275
     * @return the report publish status (note that if there is no such resource, this method will
276
     * throw ResourceNotFoundException rather than returning null).
277
     * @throws IllegalArgumentException    if any argument is null or empty string
278
     * @throws InvalidRequestException     if there is any problem with the REST API request
279
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
280
     * @throws ResourceNotFoundException   if the resource cannot be found
281
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
282
     * @throws SmartsheetException         if there is any other error during the operation
283
     */
284
    public ReportPublish getPublishStatus(long id) throws SmartsheetException {
285
        return this.getResource(REPORTS_PATH + id + "/publish", ReportPublish.class);
×
286
    }
287

288
    /**
289
     * Sets the publish status of a report and returns the new status, including the URLs of any
290
     * enabled publishing.
291
     * <p>
292
     * It mirrors to the following Smartsheet REST API method: PUT /reports/{id}/publish
293
     * <p>
294
     * Exceptions:
295
     * - InvalidRequestException : if there is any problem with the REST API request
296
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
297
     * - ResourceNotFoundException : if the resource can not be found
298
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
299
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
300
     * - SmartsheetException : if there is any other error occurred during the operation
301
     *
302
     * @param id            the ID of the report
303
     * @param reportPublish the ReportPublish object
304
     * @return the updated ReportPublish (note that if there is no such resource, this method will
305
     * throw ResourceNotFoundException rather than returning null)
306
     * @throws IllegalArgumentException    if any argument is null or empty string
307
     * @throws InvalidRequestException     if there is any problem with the REST API request
308
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
309
     * @throws ResourceNotFoundException   if the resource cannot be found
310
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
311
     * @throws SmartsheetException         if there is any other error during the operation
312
     */
313
    public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) throws SmartsheetException {
314
        return this.updateResource(REPORTS_PATH + id + "/publish", ReportPublish.class, reportPublish);
×
315
    }
316

317
    /**
318
     * Updates a report's definition (filters, grouping, summarizing, and sorting).
319
     * <p>
320
     * It mirrors to the following Smartsheet REST API method: PUT /reports/{id}/definition
321
     * <p>
322
     * This endpoint supports partial updates only on root level properties of the report definition,
323
     * such as filters, groupingCriteria, and summarizingCriteria. For example, you can update the
324
     * report's filters without affecting its grouping criteria. However, nested properties within
325
     * these objects, such as a specific filter or grouping criterion, cannot be updated individually
326
     * and require a full replacement of the respective section.
327
     * <p>
328
     * Exceptions:
329
     * - InvalidRequestException : if there is any problem with the REST API request
330
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
331
     * - ResourceNotFoundException : if the resource can not be found
332
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
333
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
334
     * - SmartsheetException : if there is any other error occurred during the operation
335
     *
336
     * @param id         the ID of the report
337
     * @param reportDefinition the ReportDefinition object containing the updated definition
338
     * @throws IllegalArgumentException    if any argument is null
339
     * @throws InvalidRequestException     if there is any problem with the REST API request
340
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
341
     * @throws ResourceNotFoundException   if the resource cannot be found
342
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
343
     * @throws SmartsheetException         if there is any other error during the operation
344
     */
345
    public void updateReportDefinition(long id, ReportDefinition reportDefinition) throws SmartsheetException {
346
        String path = REPORTS_PATH + id + "/definition";
×
347
        this.putResource(path, Result.class, reportDefinition);
×
348
    }
×
349

350
    /**
351
     * <p>Deletes a report.</p>
352
     *
353
     * <p>Mirrors the following Smartsheet REST API method: DELETE /reports/{reportId}</p>
354
     *
355
     * @param id the id of the report
356
     * @throws IllegalArgumentException    if any argument is null or empty string
357
     * @throws InvalidRequestException     if there is any problem with the REST API request
358
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
359
     * @throws ResourceNotFoundException   if the resource cannot be found
360
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
361
     * @throws SmartsheetException         if there is any other error during the operation
362
     */
363
    public void deleteReport(long id) throws SmartsheetException {
364
        this.deleteResource(REPORTS_PATH + id, Report.class);
1✔
365
    }
1✔
366

367
    /**
368
     * <p>Adds one or more specified sheet or workspace to the report scope.</p>
369
     *
370
     * @param id          the ID of the report
371
     * @param scopes A list of one or more objects denoting the sheets or workspaces associated with
372
     *               the report to be added to the report scope.
373
     * @throws IllegalArgumentException    if any argument is null or empty
374
     * @throws InvalidRequestException     if there is any problem with the REST API request
375
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
376
     * @throws ResourceNotFoundException   if the resource cannot be found
377
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
378
     * @throws SmartsheetException         if there is any other error during the operation
379
     */
380
    @Override
381
    public void addReportScope(long id, List<ReportScopeInclusion> scopes) throws SmartsheetException {
382
        Util.throwIfNull(scopes);
×
383

384
        if (scopes.isEmpty()) {
×
385
            throw new IllegalArgumentException("scopes should not be empty.");
×
386
        }
387

388
        String path = REPORTS_PATH + id + "/scope";
×
389
        HttpRequest request = createHttpRequest(smartsheet.getBaseURI().resolve(path), HttpMethod.POST);
×
390
        setRequestEntity(request, scopes);
×
391

392
        try {
393
            HttpResponse response = this.smartsheet.getHttpClient().request(request);
×
394
            if (response.getStatusCode() != 200) {
×
395
                handleError(response);
×
396
            }
397
        } finally {
398
            smartsheet.getHttpClient().releaseConnection();
×
399
        }
400
    }
×
401

402
    /**
403
     * <p>Removes one or more specified sheet or workspace from the report scope.</p>
404
     *
405
     * @param id             the ID of the report
406
     * @param scopes A list of one or more objects denoting the sheets or workspaces associated with
407
     *               the report to be removed from the report scope.
408
     * @throws IllegalArgumentException    if any argument is null or empty
409
     * @throws InvalidRequestException     if there is any problem with the REST API request
410
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
411
     * @throws ResourceNotFoundException   if the resource cannot be found
412
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
413
     * @throws SmartsheetException         if there is any other error during the operation
414
     */
415
    @Override
416
    public void removeReportScope(long id, List<ReportScopeInclusion> scopes) throws SmartsheetException {
417
        Util.throwIfNull(scopes);
×
418

419
        if (scopes.isEmpty()) {
×
420
            throw new IllegalArgumentException("scopes should not be empty.");
×
421
        }
422

423
        String path = REPORTS_PATH + id + "/scope";
×
424
        HttpRequest request = createHttpRequest(smartsheet.getBaseURI().resolve(path), HttpMethod.DELETE);
×
425
        setRequestEntity(request, scopes);
×
426

427
        try {
428
            HttpResponse response = this.smartsheet.getHttpClient().request(request);
×
429
            if (response.getStatusCode() != 200) {
×
430
                handleError(response);
×
431
            }
432
        } finally {
433
            smartsheet.getHttpClient().releaseConnection();
×
434
        }
435
    }
×
436

437
    /**
438
     * <p>Add reportColumns to a report.</p>
439
     *
440
     * <p>It mirrors to the following Smartsheet REST API method: POST /reports/{reportId}/reportColumns</p>
441
     *
442
     * <p>Note: All indexes of the reportColumns must be equal.</p>
443
     *
444
     * @param reportId the ID of the report
445
     * @param reportColumns  the list of reportColumns to add (must contain 1-400 items)
446
     * @return the list of reportColumns that were added
447
     * @throws IllegalArgumentException    if any argument is null or empty
448
     * @throws InvalidRequestException     if there is any problem with the REST API request
449
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
450
     * @throws ResourceNotFoundException   if the resource cannot be found
451
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
452
     * @throws SmartsheetException         if there is any other error during the operation
453
     */
454
    @Override
455
    public List<ReportColumn> addReportColumns(long reportId, List<ReportColumn> reportColumns) throws SmartsheetException {
456
        Util.throwIfNull(reportColumns);
1✔
457

458
        if (reportColumns.isEmpty()) {
1✔
459
            throw new IllegalArgumentException("reportColumns should not be empty.");
×
460
        }
461

462
        return this.postAndReceiveList(REPORTS_PATH + reportId + "/columns", reportColumns, ReportColumn.class);
1✔
463
    }
464

465
    /**
466
     * <p>Create a new report.</p>
467
     *
468
     * <p>It mirrors to the following Smartsheet REST API method: POST /reports</p>
469
     *
470
     * <p>Creates a new report by specifying name, destination, scope, columns and definition.</p>
471
     *
472
     * @param request the CreateReportRequest containing report specifications
473
     * @return the CreateReportResult containing the newly created report information
474
     * @throws IllegalArgumentException    if any argument is null
475
     * @throws InvalidRequestException     if there is any problem with the REST API request
476
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
477
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
478
     * @throws SmartsheetException         if there is any other error during the operation
479
     */
480
    @Override
481
    public CreateReportResult createReport(CreateReportRequest request) throws SmartsheetException {
482
        Util.throwIfNull(request);
1✔
483

484
        return this.createResource(REPORTS, CreateReportResult.class, request);
1✔
485
    }
486

487
    /**
488
     * Get the path of a report (workspace/folder hierarchy).
489
     * <p>
490
     * It mirrors to the following Smartsheet REST API method: GET /reports/{reportId}/path
491
     *
492
     * @param reportId the report id
493
     * @return the container path
494
     * @throws SmartsheetException the smartsheet exception
495
     */
496
    @Override
497
    public ReportPathNode getReportPath(long reportId) throws SmartsheetException {
498
        return this.getResource(REPORTS_PATH + reportId + "/path", ReportPathNode.class);
1✔
499
    }
500

501
    private void setRequestEntity(HttpRequest request, Object object) throws JSONSerializerException {
502
        ByteArrayOutputStream objectBytesStream = new ByteArrayOutputStream();
×
503
        this.smartsheet.getJsonSerializer().serialize(object, objectBytesStream);
×
504
        HttpEntity entity = new HttpEntity();
×
505
        entity.setContentType(JSON_CONTENT_TYPE);
×
506
        entity.setContent(new ByteArrayInputStream(objectBytesStream.toByteArray()));
×
507
        entity.setContentLength(objectBytesStream.size());
×
508
        request.setEntity(entity);
×
509
    }
×
510
}
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

© 2026 Coveralls, Inc