DriveItem.java
/*
* onedrive-java-sdk - A Java SDK to access OneDrive drives and files.
* Copyright © 2023-2025 Andy Miles (andy.miles@amilesend.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.amilesend.onedrive.resource.item;
import com.amilesend.client.connection.file.ProgressReportingRequestBody;
import com.amilesend.client.connection.file.TransferProgressCallback;
import com.amilesend.client.parse.strategy.GsonExclude;
import com.amilesend.client.parse.strategy.GsonSerializeExclude;
import com.amilesend.onedrive.connection.OneDriveConnection;
import com.amilesend.onedrive.resource.activities.ItemActivity;
import com.amilesend.onedrive.resource.item.type.Audio;
import com.amilesend.onedrive.resource.item.type.Deleted;
import com.amilesend.onedrive.resource.item.type.File;
import com.amilesend.onedrive.resource.item.type.FileSystemInfo;
import com.amilesend.onedrive.resource.item.type.Folder;
import com.amilesend.onedrive.resource.item.type.GeoCoordinates;
import com.amilesend.onedrive.resource.item.type.Image;
import com.amilesend.onedrive.resource.item.type.ItemReference;
import com.amilesend.onedrive.resource.item.type.Package;
import com.amilesend.onedrive.resource.item.type.Permission;
import com.amilesend.onedrive.resource.item.type.Photo;
import com.amilesend.onedrive.resource.item.type.Preview;
import com.amilesend.onedrive.resource.item.type.PublicationFacet;
import com.amilesend.onedrive.resource.item.type.RemoteItem;
import com.amilesend.onedrive.resource.item.type.SearchResult;
import com.amilesend.onedrive.resource.item.type.SharePointIds;
import com.amilesend.onedrive.resource.item.type.Shared;
import com.amilesend.onedrive.resource.item.type.SpecialFolder;
import com.amilesend.onedrive.resource.item.type.ThumbnailSet;
import com.amilesend.onedrive.resource.item.type.Video;
import com.amilesend.onedrive.resource.request.AddPermissionRequest;
import com.amilesend.onedrive.resource.request.CreateSharingLinkRequest;
import com.amilesend.onedrive.resource.request.PreviewRequest;
import com.google.common.annotations.VisibleForTesting;
import com.google.gson.annotations.SerializedName;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import okhttp3.RequestBody;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static com.amilesend.onedrive.connection.OneDriveConnection.JSON_MEDIA_TYPE;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.DRIVE_ITEM_PAGE_PARSER;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.DRIVE_ITEM_PARSER;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.ITEM_ACTIVITY_LIST_PARSER;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.THUMBNAIL_SET_LIST_PARSER;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.newDriveItemVersionListParser;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.newPermissionListParser;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.newPermissionParser;
import static com.amilesend.onedrive.parse.resource.parser.Parsers.newPreviewParser;
import static com.amilesend.onedrive.resource.ResourceHelper.objectDefinedEquals;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
/**
* Describes a resource stored in a drive.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/resources/driveitem">
* API Documentation</a>.
*/
/*
* TODO:
* 1. Implement support for upload sessions if there's a use-case for it
* (https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createuploadsession)
* 2. Implement support for URL based uploads if there's a use-case for it
* (https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_upload_url)
*/
@Getter
@SuperBuilder
@ToString(callSuper = true)
public class DriveItem extends BaseItem {
public static final String DRIVE_ITEM_BASE_URL_PATH = "/drive/items/";
private static final String CONTENT_URL_SUFFIX = "/content";
private static final int MAX_QUERY_LENGTH = 1000;
/** The audio file attributes (read-only). */
private final Audio audio;
/** An eTag for the content of the item (read-only). */
private final String cTag;
/** Indicates if an item is a file (read-only). */
private final File file;
/** Describes if a given drive item is a folder resource type (read-only). */
private final Folder folder;
/** The image attributes for a file (read-only). */
private final Image image;
/** The geographic coordinates and elevation of a file (read-only). */
private final GeoCoordinates location;
/** If defined, malware was detected in the file (read-only). */
private final Object malware;
/** Indicates that a drive item is the top level item in a collection of items (read-only). */
@SerializedName("package")
private final Package _package;
/** The photo attributes for a drive item file (read-only). */
private final Photo photo;
/** The published status of a drive item or version (read-only). */
private final PublicationFacet publication;
/** Indicates that a drive item references one that exists in another drive (read-only). */
private final RemoteItem remoteItem;
/* An empty object if defined; else is null */
/** If defined, indicates that the item is the top-most folder in the drive (read-only). */
private final Object root;
/** Indicates that the item is in response to a search query (read-only). */
private final SearchResult searchResult;
/** Indicates that a drive item has been shared with others (read-only). */
private final Shared shared;
/** SharePoint resource identifiers for SharePoint and Business account items (read-only). */
private final SharePointIds sharepointIds;
/** The size of the item in bytes (read-only). */
private final long size;
/** Describes if the item is a special managed folder (read-only). */
private final SpecialFolder specialFolder;
/** The video file attributes (read-only). */
private final Video video;
/** The URL that can be used to download the file's content (read-only). */
@SerializedName("@microsoft.graph.downloadUrl")
@GsonSerializeExclude
private final String downloadUrl;
/** Gets the underlying connection instance. */
@GsonExclude
private final OneDriveConnection connection;
/** Indicates if an item was deleted (read-only). */
private Deleted deleted;
@Setter
/** Describes drive (client-side) properties of the local version of a drive item. */
private FileSystemInfo fileSystemInfo;
/**
* Describes how to handle conflicts upon copy/move operations. Valid values include:
* <ul>
* <li>{@literal fail}</li>
* <li>{@literal replace}</li>
* <li>{@literal rename}</li>
* </ul>
* This member is write-only.
*/
@SerializedName("@microsoft.graph.conflictBehavior")
@Setter
private String conflictBehavior;
/** The source URL for remote uploading of file contents (write-only). Currently not tested nor supported. */
@EqualsAndHashCode.Exclude
@GsonSerializeExclude
@SerializedName("@microsoft.graph.sourceUrl")
@Setter
private String sourceUrl;
////////////////////////
// Download
////////////////////////
/**
* Downloads the drive item and reports transfer progress to the given {@link TransferProgressCallback}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get_content">
* API Documentation</a>.
*
* @param folderPath the path of the folder to download the drive item content to
* @param callback the callback to inform of transfer progress
*/
public void download(@NonNull final Path folderPath, @NonNull final TransferProgressCallback callback) {
connection.download(
connection.newRequestBuilder()
.url(getContentUrl(validateAndGetUrlEncodedId()))
.build(),
folderPath,
getName(),
getSize(),
callback);
}
/**
* Downloads the drive item asynchronously that reports transfer progress and completion to the specified
* {@link TransferProgressCallback}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get_content">
* API Documentation</a>.
*
* @param folderPath the path of the folder to download the drive item content to
* @param callback the callback to inform of transfer progress
* @return the CompletableFuture used to fetch the number of bytes downloaded
*/
public CompletableFuture<Long> downloadAsync(
@NonNull final Path folderPath,
@NonNull final TransferProgressCallback callback) {
return connection.downloadAsync(
connection.newRequestBuilder()
.url(getContentUrl(validateAndGetUrlEncodedId()))
.build(),
folderPath,
getName(),
getSize(),
callback);
}
////////////////////////
// Upload
////////////////////////
/**
* Uploads a file to replace the contents of this {@code DriveItem} and reports the
* transfer status to the given {@link TransferProgressCallback}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content">
* API Documentation</a>.
*
* @param filePath the file to upload
* @param callback the callback to inform of transfer progress
* @return the updated drive item information
* @throws IOException if unable to read or determine the file's content type
*/
public DriveItem upload(@NonNull final Path filePath, @NonNull final TransferProgressCallback callback)
throws IOException {
return uploadInternal(
getContentUrl(validateAndGetUrlEncodedId()),
ProgressReportingRequestBody.builder()
.file(filePath)
.callback(callback)
.build());
}
/**
* Uploads a file asynchronously to replace the contents of this {@code DriveItem} and reports the
* transfer status to the given {@link TransferProgressCallback}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content">
* API Documentation</a>.
*
* @param filePath the file to upload
* @param callback the callback to inform of transfer progress
* @return the CompletableFuture to fetch the updated drive item information
* @throws IOException if unable to read or determine the file's content type
*/
public CompletableFuture<DriveItem> uploadAsync(
@NonNull final Path filePath,
@NonNull final TransferProgressCallback callback) throws IOException {
return uploadInternalAsync(
getContentUrl(validateAndGetUrlEncodedId()),
ProgressReportingRequestBody.builder()
.file(filePath)
.callback(callback)
.build());
}
////////////////////////
// uploadNew
////////////////////////
/**
* Uploads a new file as a child of this {@code DriveItem} and reports the transfer status to the given
* {@link TransferProgressCallback}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content">
* API Documentation</a>.
*
* @param filePath the file to upload
* @param callback the callback to inform of transfer progress
* @return the new child drive item associated with the uploaded file
* @throws IOException if unable to read or determine the file's content type
*/
public DriveItem uploadNew(@NonNull final Path filePath, @NonNull final TransferProgressCallback callback)
throws IOException {
return uploadInternal(
getContentUrl(validateAndGetUrlEncodedId(), filePath.getFileName().toString()),
ProgressReportingRequestBody.builder()
.file(filePath)
.callback(callback)
.build());
}
/**
* Uploads a new file asynchronously as a child of this {@code DriveItem} and reports the transfer status to the
* given {@link TransferProgressCallback}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content">
* API Documentation</a>.
*
* @param filePath the file to upload
* @param callback the callback to inform of transfer progress
* @return the completable future to fetch the updated drive item information
* @throws IOException if unable to read or determine the file's content type
*/
public CompletableFuture<DriveItem> uploadNewAsync(
@NonNull final Path filePath,
@NonNull final TransferProgressCallback callback) throws IOException {
return uploadInternalAsync(
getContentUrl(validateAndGetUrlEncodedId(), filePath.getFileName().toString()),
ProgressReportingRequestBody.builder()
.file(filePath)
.callback(callback)
.build());
}
private DriveItem uploadInternal(final String url, final ProgressReportingRequestBody body) {
return connection.execute(
connection.newRequestBuilder()
.url(url)
.addHeader(CONTENT_TYPE, body.contentType().toString())
.put(body)
.build(),
DRIVE_ITEM_PARSER);
}
private CompletableFuture<DriveItem> uploadInternalAsync(
final String url,
final ProgressReportingRequestBody body) {
return connection.executeAsync(
connection.newRequestBuilder()
.url(url)
.addHeader(CONTENT_TYPE, body.contentType().toString())
.put(body)
.build(),
DRIVE_ITEM_PARSER);
}
////////////////////////
// CRUD
////////////////////////
/**
* Creates a new {@code DriveItem} as a child of {@code this}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_post_children">
* API Documentation</a>.
*
* @param newChildDriveItem the new drive item to create
* @return the new drive item
*/
public DriveItem create(@NonNull final DriveItem newChildDriveItem) {
return connection.execute(
connection.newWithBodyRequestBuilder()
.url(getChildrenUrl(validateAndGetUrlEncodedId()))
.post(RequestBody.create(newChildDriveItem.toJson(), JSON_MEDIA_TYPE))
.build(),
DRIVE_ITEM_PARSER);
}
/**
* Updates this drive item.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_update">
* API Documentation</a>.
*
* @return the updated drive item
*/
public DriveItem update() {
return connection.execute(
connection.newWithBodyRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.toString())
.patch(RequestBody.create(toJson(), JSON_MEDIA_TYPE))
.build(),
DRIVE_ITEM_PARSER);
}
/**
* Moves this {@code DriveItem} as a child to the given {@code newParentId}, updates the name, or both.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_move">
* API Documentation</a>.
*
* @param destinationParentId the new parent identifier
* @param newName the new name
* @return the updated drive item
*/
public DriveItem move(final String destinationParentId, final String newName) {
validateDestinationParentIdAndNewName(destinationParentId, newName);
return update();
}
/**
* Copies this {@code DriveItem} to a child of the given {@code destinationParentId} and updates the name of the
* copied {@link DriveItem}.
*
* @param destinationParentId the new destination parent identifier
* @param newName the new name
* @return the {@code AsyncJob} that can be used to poll for the remote asynchronous operation progress.
* @see AsyncJob
*/
public AsyncJob copy(final String destinationParentId, final String newName) {
validateDestinationParentIdAndNewName(destinationParentId, newName);
final String monitoringUrl = connection.executeRemoteAsync(
connection.newWithBodyRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/copy")
.toString())
.post(RequestBody.create(toJson(), JSON_MEDIA_TYPE))
.build());
return new AsyncJob(monitoringUrl, connection);
}
/**
* Deletes this drive item.
*/
public void delete() {
connection.execute(
connection.newRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.toString())
.delete()
.build());
// Set the deleted state for this drive item for consumers that still have reference to the object.
this.deleted = Deleted.builder().build();
}
////////////////////////
// References (has-a)
////////////////////////
/**
* Queries and fetches the activities associated with this {@code DriveItem}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/activities_list">
* API Documentation</a>.
*
* @return the list of activities
*/
public List<ItemActivity> getActivities() {
return connection.execute(
connection.newRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/activities")
.toString())
.build(),
ITEM_ACTIVITY_LIST_PARSER);
}
/**
* Fetches the list of child {@link DriveItem}s associated with this {@code DriveItem}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children">
* API Documentation</a>.
*
* @return list of child drive items
*/
public List<DriveItem> getChildren() {
final List<DriveItem> changes = new ArrayList<>();
final String urlEncodedId = validateAndGetUrlEncodedId();
DriveItemPage currentPage = null;
do {
currentPage = connection.execute(
connection.newRequestBuilder()
.url(getChildrenUrl(currentPage, urlEncodedId))
.build(),
DRIVE_ITEM_PAGE_PARSER);
changes.addAll(currentPage.getValue());
} while (hasNextPage(currentPage));
return changes;
}
/**
* Fetches the list of versions of this {@code DriveItem}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_versions">
* API Documentation</a>.
*
* @return the list of versions
* @see DriveItemVersion
*/
public List<DriveItemVersion> getVersions() {
return connection.execute(
connection.newRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/versions")
.toString())
.build(),
newDriveItemVersionListParser(getId(), getName()));
}
/**
* Fetches the list of permissions associated with this {@code DriveItem}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_versions">
* API Documentation</a>.
*
* @return the list of permissions
* @see Permission
*/
public List<Permission> getPermissions() {
return connection.execute(
connection.newRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/permissions")
.toString())
.build(),
newPermissionListParser(getId()));
}
/**
* Adds a permission to this {@code DriveItem} for the given request.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_invite">
* API Documentation</a>.
*
* @param requestBody the descriptor of the permission to add
* @return the list of permissions for the associate item.
*/
public List<Permission> addPermission(@NonNull final AddPermissionRequest requestBody) {
return connection.execute(
connection.newWithBodyRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/invite")
.toString())
.post(RequestBody.create(
connection.getGsonFactory().getInstance(connection).toJson(requestBody),
JSON_MEDIA_TYPE))
.build(),
newPermissionListParser(getId()));
}
/**
* Creates a sharing link for the given request.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink">
* API Documentation</a>.
*
* @param requestBody the descriptor of the type of link to share
* @return the sharing permissions that includes the link
*/
public Permission createSharingLink(@NonNull final CreateSharingLinkRequest requestBody) {
return connection.execute(
connection.newWithBodyRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/createLink")
.toString())
.post(RequestBody.create(
connection.getGsonFactory().getInstance(connection).toJson(requestBody),
JSON_MEDIA_TYPE))
.build(),
newPermissionParser(getId()));
}
/**
* Gets the embeddable file preview URLs for inclusion in a web-based UI. Note: For long-lived embeddable links,
* use {@link #createSharingLink(CreateSharingLinkRequest)} instead.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_preview">
* API Documentation</a>.
*
* @param requestBody the preview item request body
* @return the preview URLs
*/
public Preview previewItem(@NonNull final PreviewRequest requestBody) {
return connection.execute(
connection.newWithBodyRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/preview")
.toString())
.post(RequestBody.create(
connection.getGsonFactory().getInstance(connection).toJson(requestBody),
JSON_MEDIA_TYPE))
.build(),
newPreviewParser(getId()));
}
/**
* Fetches the list of thumbnail sets associated with this {@code DriveItem}.
*
* @return the list of thumbnail sets
* @see ThumbnailSet
*/
public List<ThumbnailSet> getThumbnails() {
return connection.execute(
connection.newRequestBuilder()
.url(new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(validateAndGetUrlEncodedId())
.append("/thumbnails")
.toString())
.build(),
THUMBNAIL_SET_LIST_PARSER);
}
/**
* Search for items associated with this {@code DriveItem}.
* <p>
* <a href="https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search">
* API Documentation</a>.
*
* @param query the search query
* @return the list of drive items associated with the query
*/
public List<DriveItem> search(final String query) {
Validate.notBlank(query, "query must not be blank");
Validate.isTrue(query.length() < MAX_QUERY_LENGTH,
"query length must be less than " + MAX_QUERY_LENGTH);
final List<DriveItem> results = new ArrayList<>();
DriveItemPage currentPage = null;
do {
currentPage = connection.execute(
connection.newRequestBuilder()
.url(getSearchUrl(currentPage, validateAndGetUrlEncodedId(), query))
.build(),
DRIVE_ITEM_PAGE_PARSER);
results.addAll(currentPage.getValue());
} while (hasNextPage(currentPage));
return results;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
if (!super.equals(obj)) {
return false;
}
final DriveItem driveItem = (DriveItem) obj;
return getSize() == driveItem.getSize()
&& Objects.equals(getAudio(), driveItem.getAudio())
&& Objects.equals(getCTag(), driveItem.getCTag())
&& Objects.equals(getDeleted(), driveItem.getDeleted())
&& Objects.equals(getFile(), driveItem.getFile())
&& Objects.equals(getFileSystemInfo(), driveItem.getFileSystemInfo())
&& Objects.equals(getFolder(), driveItem.getFolder())
&& Objects.equals(getImage(), driveItem.getImage())
&& Objects.equals(getLocation(), driveItem.getLocation())
&& objectDefinedEquals(getMalware(), driveItem.getMalware())
&& Objects.equals(get_package(), driveItem.get_package())
&& Objects.equals(getPhoto(), driveItem.getPhoto())
&& Objects.equals(getPublication(), driveItem.getPublication())
&& Objects.equals(getRemoteItem(), driveItem.getRemoteItem())
&& objectDefinedEquals(getRoot(), driveItem.getRoot())
&& Objects.equals(getSearchResult(), driveItem.getSearchResult())
&& Objects.equals(getShared(), driveItem.getShared())
&& Objects.equals(getSharepointIds(), driveItem.getSharepointIds())
&& Objects.equals(getSpecialFolder(), driveItem.getSpecialFolder())
&& Objects.equals(getVideo(), driveItem.getVideo())
&& Objects.equals(getConflictBehavior(), driveItem.getConflictBehavior());
}
@Override
public int hashCode() {
return Objects.hash(
super.hashCode(),
getAudio(),
getCTag(),
getDeleted(),
getFile(),
getFileSystemInfo(),
getFolder(),
getImage(),
getLocation(),
Objects.nonNull(getMalware()),
get_package(),
getPhoto(),
getPublication(),
getRemoteItem(),
Objects.nonNull(getRoot()),
getSearchResult(),
getShared(),
getSharepointIds(),
getSize(),
getSpecialFolder(),
getVideo(),
getConflictBehavior());
}
@VisibleForTesting
String toJson() {
return connection.getGsonFactory().getInstance(connection).toJson(this);
}
private String validateAndGetUrlEncodedId() {
final String driveItemId = getId();
Validate.notBlank(driveItemId, "id must not be blank");
return URLEncoder.encode(driveItemId, StandardCharsets.UTF_8);
}
private void validateDestinationParentIdAndNewName(final String destinationParentId, final String newName) {
Validate.isTrue(StringUtils.isNotBlank(destinationParentId)
|| StringUtils.isNotBlank(newName),
"Both destinationParentId and newName must not be blank");
final boolean isSameDestinationId = Optional.ofNullable(getParentReference())
.map(r -> r.getId().equals(destinationParentId))
.orElse(false);
final boolean isSameName = StringUtils.equals(getName(), newName);
Validate.isTrue(!(isSameDestinationId && isSameName),
"Both destinationParentId and newName must not be the same as the original drive item");
if (StringUtils.isNotBlank(destinationParentId)) {
final ItemReference parentReference = getParentReference() != null
? getParentReference()
: ItemReference.builder().id(destinationParentId).build();
setParentReference(parentReference);
}
if (StringUtils.isNotBlank(newName)) {
setName(newName);
}
}
private String getContentUrl(final String urlEncodedDriveItemId) {
return new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(urlEncodedDriveItemId)
.append(CONTENT_URL_SUFFIX)
.toString();
}
private String getContentUrl(final String urlEncodedDriveItemId, final String filename) {
return new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(urlEncodedDriveItemId)
.append(":/")
.append(URLEncoder.encode(filename, StandardCharsets.UTF_8))
.append(":")
.append(CONTENT_URL_SUFFIX)
.toString();
}
private String getChildrenUrl(final DriveItemPage page, final String urlEncodedDriveItemId) {
return page == null ? getChildrenUrl(urlEncodedDriveItemId) : page.getNextLink();
}
private String getChildrenUrl(final String urlEncodedDriveItemId) {
return new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(urlEncodedDriveItemId)
.append("/children")
.toString();
}
private String getSearchUrl(
final DriveItemPage page,
final String urlEncodedDriveItemId,
final String searchQuery) {
return page == null
? new StringBuilder(connection.getBaseUrl())
.append(DRIVE_ITEM_BASE_URL_PATH)
.append(urlEncodedDriveItemId)
.append("/search(q='")
.append(URLEncoder.encode(searchQuery, StandardCharsets.UTF_8))
.append("')")
.toString()
: page.getNextLink();
}
}