package de.tuberlin.onedrivesdk.common;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import de.tuberlin.onedrivesdk.folder.OneFolder;
import de.tuberlin.onedrivesdk.OneDriveException;
import de.tuberlin.onedrivesdk.drive.DriveUser;
import de.tuberlin.onedrivesdk.file.ConcreteOneFile;
import de.tuberlin.onedrivesdk.file.OneFile;
import de.tuberlin.onedrivesdk.folder.ConcreteOneFolder;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* The root class of all files and folder types that can be accessed through this sdk.
*/
public abstract class OneItem {
/**
* The SDK object.
*/
protected ConcreteOneDriveSDK api;
/**
* The OneDrive id of the resource.
*/
protected String id = "";
/**
* The Name.
*/
protected String name = "";
/**
* The created by reference. Possible keys are 'user', 'application' and 'device'.
*/
protected HashMap<String, DriveUser> createdBy = new HashMap<>();
/**
* The creation timestamp of this item.
*/
protected String createdDateTime;
/**
* The modified by reference. Possible keys are 'user', 'application' and 'device'.
*/
protected HashMap<String, DriveUser> lastModifiedBy = new HashMap<>();
/**
* The last modified timestamp of this item.
*/
protected String lastModifiedDateTime = "";
/**
* The cTag.
*/
protected String cTag = "";
/**
* The eTag.
*/
protected String eTag = "";
/**
* The size of an item in bytes.
*/
protected long size = 0;
/**
* URL that displays the resource in the browser.
*/
protected String webUrl = "";
/**
* The parent folder reference.
*/
protected ParentReference parentReference;
/**
* The raw JSON which is received from the OneDrive API.
*/
protected String rawJson = "";
/**
* A Url that can be used to download this file's content.
*/
@SerializedName("@content.downloadUrl")
protected String downloadUrl;
/**
* A timestamp of the last refresh.
*/
private long lastRefresh;
/**
* Parse a OneItem object from JSON.
*
* @param json JSON from the OneDrive API
* @return OneItem
* @throws ParseException if the JSON can not be parsed
* @throws OneDriveException if the JSON contains an OneDrive Error object from the API
*/
public static OneItem fromJSON(String json) throws ParseException, OneDriveException {
JSONObject root = getJsonObject(json);
OneDriveError error;
if ((error = OneDriveError.parseError(json)) != null) {
throw new OneDriveException(error.toString());
}
Gson gson = new Gson();
if (root.containsKey("file")) {
return gson.fromJson(json, ConcreteOneFile.class).setLastRefresh(System.currentTimeMillis());
} else {
return gson.fromJson(json, ConcreteOneFolder.class).setLastRefresh(System.currentTimeMillis());
}
}
/**
* Parse a List of OneItems from JSON.
*
* @param json JSON from the OneDrive API
* @return a List of OneItems
* @throws ParseException if the JSON can not be parsed
* @throws OneDriveException if the JSON contains an OneDrive Error object from the API
*/
public static List<OneItem> parseItemsFromJson(String json) throws ParseException, OneDriveException {
return OneItem.parseItemsFromJson(json, OneItemType.ALL);
}
/**
* Parse a List of OneItems from JSON.
*
* @param json JSON from the OneDrive API
* @param type OneItemType, can be used to define which type of items should be parsed
* @return items from json
* @throws ParseException if the JSON can not be parsed
* @throws OneDriveException if the json dose not contain a 'value' attribute
*/
public static List<OneItem> parseItemsFromJson(String json, OneItemType type) throws ParseException, OneDriveException {
ArrayList<OneItem> itemList = new ArrayList<>();
JSONObject root = getJsonObject(json);
if (root.containsKey("value")) {
JSONArray values = (JSONArray) root.get("value");
for (Object object : values) {
JSONObject itemJson = (JSONObject) object;
OneItem item = OneItem.fromJSON(itemJson.toJSONString());
switch (type) {
case FILE:
if (item instanceof OneFile) itemList.add(item);
break;
case FOLDER:
if (item instanceof OneFolder) itemList.add(item);
break;
case ALL:
itemList.add(item);
}
}
} else {
throw new OneDriveException("Cannot parse items from JSON. Missing argument 'value'.");
}
return itemList;
}
/**
* Parse JSON from string and return the JSONObject
*
* @param json from the OneDrive API
* @return JSONObject
* @throws ParseException if the JSON can not be parsed
*/
private static JSONObject getJsonObject(String json) throws ParseException {
JSONParser parser = new JSONParser();
JSONObject root;
root = (JSONObject) parser.parse(json);
return root;
}
/**
* Gets the name of the item.
*
* @return name
*/
public String getName() {
return name;
}
/**
* Sets the api object.
*
* @param api the api object
* @return the identity
* @throws OneDriveException if the api is null
*/
public OneItem setApi(ConcreteOneDriveSDK api) throws OneDriveException {
if (api == null) {
throw new OneDriveException("The provided api object can not be null!");
}
this.api = api;
return this;
}
/**
* Gets the id of the item.
*
* @return id
*/
public String getId() {
return this.id;
}
/**
* Delete the item.
*
* @return true if the item was deleted from OneDrive.
* @throws IOException
* @throws OneDriveException
*/
public boolean delete() throws IOException, OneDriveException {
return this.api.deleteItem(this);
}
/**
* Gets the cTag.
*
* @return cTag
*/
public String getCTag() {
return this.cTag;
}
/**
* Gets the eTag.
*
* @return eTag
*/
public String getETag() {
return this.eTag;
}
/**
* The created by reference. Possible keys are 'user', 'application' and 'device'.
*
* @return created by
*/
public HashMap<String, DriveUser> getCreatedBy() {
return this.createdBy;
}
/**
* The creation timestamp of this item.
*
* @return unix formatted timestamp
*/
public long getCreatedDateTime() {
try {
return this.parseTimestamp(this.createdDateTime).getTime() / 1000;
} catch (java.text.ParseException e) {
return 0;
}
}
/**
* The modified by reference. Possible keys are 'user', 'application' and 'device'.
*
* @return last modified by
*/
public HashMap<String, DriveUser> getLastModifiedBy() {
return this.lastModifiedBy;
}
/**
* The last modified timestamp of this item.
*
* @return unix formatted timestamp
*/
public long getLastModifiedDateTime() {
try {
return this.parseTimestamp(this.lastModifiedDateTime).getTime() / 1000;
} catch (java.text.ParseException e) {
return 0;
}
}
/**
* Parse a timestamp.
*
* @param dateTime Format: 0000-00-00T00:00:00
* @return timestamp
* @throws java.text.ParseException if the date can not be parsed
*/
private Date parseTimestamp(String dateTime) throws java.text.ParseException {
if (dateTime != null && dateTime.indexOf('.') != -1) {
dateTime = dateTime.substring(0, dateTime.indexOf('.'));
DateFormat df = new SimpleDateFormat("y-M-d'T'H:m:s");
return df.parse(dateTime);
} else {
throw new java.text.ParseException(dateTime, -1);
}
}
/**
* Gets the size of this item in bytes.
*
* @return size
*/
public long getSize() {
return this.size;
}
/**
* Gets the URL that displays the resource in the browser.
*
* @return web url
*/
public String getWebUrl() {
return this.webUrl;
}
/**
* Gets the parent folder.
*
* @return parent folder
* @throws IOException
* @throws OneDriveException
*/
public OneFolder getParentFolder() throws IOException, OneDriveException {
return api.getFolderById(this.parentReference.id);
}
/**
* Gets the raw JSON which is received from the OneDrive API.
*
* @return raw json
*/
public String getRawJson() {
return rawJson;
}
/**
* Sets the raw json.
*
* @param rawJson json
* @return raw json
*/
public OneItem setRawJson(String rawJson) {
this.rawJson = rawJson;
return this;
}
/**
* Gets the timestamp of the last refresh.
*
* @return timestamp in milliseconds
*/
public long getLastRefresh() {
return lastRefresh;
}
/**
* Sets the timestamp of the last refresh.
*
* @param lastRefresh timestamp in milliseconds
* @return last refresh
*/
public OneItem setLastRefresh(long lastRefresh) {
this.lastRefresh = lastRefresh;
return this;
}
/**
* Refresh the item state.
*
* @return item the reference of this item will be another one.
* @throws IOException
* @throws OneDriveException
*/
public OneItem refreshItem() throws IOException, OneDriveException {
if(this instanceof OneFile){
return (OneItem) api.getFileById(id);
} else {
return (OneItem) api.getFolderById(id);
}
}
/**
* Is file.
*
* @return boolean
*/
public abstract boolean isFile();
/**
* Is folder.
*
* @return boolean
*/
public abstract boolean isFolder();
}