Loading src/com/owncloud/android/lib/common/utils/WebDavFileUtils.java 0 → 100644 +103 −0 Original line number Diff line number Diff line /** * Nextcloud Android client application * * @author Mario Danic * Copyright (C) 2017 Mario Danic * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.owncloud.android.lib.common.utils; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; import com.owncloud.android.lib.resources.files.RemoteFile; import org.apache.jackrabbit.webdav.MultiStatus; import java.util.ArrayList; /** * WebDav helper. */ public class WebDavFileUtils { /** * Read the data retrieved from the server about the contents of the target folder * * * @param remoteData Full response got from the server with the data of the target * folder and its direct children. * @param client Client instance to the remote server where the data were * retrieved. * @return */ public ArrayList<Object> readData(MultiStatus remoteData, OwnCloudClient client, boolean isReadFolderOperation, boolean isSearchOperation, String username) { ArrayList<Object> mFolderAndFiles = new ArrayList<Object>(); WebdavEntry we; int start = 1; if (isReadFolderOperation) { we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath()); mFolderAndFiles.add(fillOCFile(we)); } else { start = 0; } String stripString = client.getWebdavUri().getPath(); if (isSearchOperation && username != null) { stripString = stripString + "/files/" + username; } // loop to update every child RemoteFile remoteFile = null; for (int i = start; i < remoteData.getResponses().length; i++) { /// new OCFile instance with the data from the server we = new WebdavEntry(remoteData.getResponses()[i], stripString); remoteFile = fillOCFile(we); mFolderAndFiles.add(remoteFile); } return mFolderAndFiles; } /** * Creates and populates a new {@link RemoteFile} object with the data read from the server. * * @param we WebDAV entry read from the server for a WebDAV resource (remote file or folder). * @return New OCFile instance representing the remote resource described by we. */ private RemoteFile fillOCFile(WebdavEntry we) { RemoteFile file = new RemoteFile(we.decodedPath()); file.setCreationTimestamp(we.createTimestamp()); file.setLength(we.contentLength()); file.setMimeType(we.contentType()); file.setModifiedTimestamp(we.modifiedTimestamp()); file.setEtag(we.etag()); file.setPermissions(we.permissions()); file.setRemoteId(we.remoteId()); file.setSize(we.size()); file.setQuotaUsedBytes(we.quotaUsedBytes()); file.setQuotaAvailableBytes(we.quotaAvailableBytes()); file.setFavorite(we.isFavorite()); return file; } } src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java +16 −14 Original line number Diff line number Diff line Loading @@ -24,6 +24,19 @@ package com.owncloud.android.lib.resources.files; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; Loading @@ -34,19 +47,6 @@ import java.util.Iterator; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; /** * Remote operation performing the download of a remote file in the ownCloud server. * Loading @@ -64,6 +64,8 @@ public class DownloadRemoteFileOperation extends RemoteOperation { private String mEtag = ""; private GetMethod mGet; private String mRemotePath; private String mLocalFolderPath; Loading src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java +9 −37 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.common.utils.WebDavFileUtils; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavConstants; Loading @@ -50,7 +51,6 @@ public class ReadRemoteFolderOperation extends RemoteOperation { private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName(); private String mRemotePath; private ArrayList<Object> mFolderAndFiles; /** * Constructor Loading Loading @@ -86,7 +86,8 @@ public class ReadRemoteFolderOperation extends RemoteOperation { if (isSuccess) { // get data from remote folder MultiStatus dataInServer = query.getResponseBodyAsMultiStatus(); readData(dataInServer, client); WebDavFileUtils webDavFileUtils = new WebDavFileUtils(); ArrayList<Object> mFolderAndFiles = webDavFileUtils.readData(dataInServer, client, true, false, ""); // Result of the operation result = new RemoteOperationResult(true, status, query.getResponseHeaders()); Loading @@ -103,7 +104,6 @@ public class ReadRemoteFolderOperation extends RemoteOperation { } catch (Exception e) { result = new RemoteOperationResult(e); } finally { if (query != null) query.releaseConnection(); // let the connection available for other methods Loading @@ -126,34 +126,6 @@ public class ReadRemoteFolderOperation extends RemoteOperation { return (status == HttpStatus.SC_MULTI_STATUS); } /** * Read the data retrieved from the server about the contents of the target folder * * * @param remoteData Full response got from the server with the data of the target * folder and its direct children. * @param client Client instance to the remote server where the data were * retrieved. * @return */ private void readData(MultiStatus remoteData, OwnCloudClient client) { mFolderAndFiles = new ArrayList<Object>(); // parse data from remote folder WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath()); mFolderAndFiles.add(fillOCFile(we)); // loop to update every child RemoteFile remoteFile = null; for (int i = 1; i < remoteData.getResponses().length; ++i) { /// new OCFile instance with the data from the server we = new WebdavEntry(remoteData.getResponses()[i], client.getWebdavUri().getPath()); remoteFile = fillOCFile(we); mFolderAndFiles.add(remoteFile); } } /** * Creates and populates a new {@link RemoteFile} object with the data read from the server. Loading src/com/owncloud/android/lib/resources/files/SearchOperation.java 0 → 100644 +248 −0 Original line number Diff line number Diff line /** * Nextcloud Android client application * * @author Mario Danic * Copyright (C) 2017 Mario Danic * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.owncloud.android.lib.resources.files; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.WebDavFileUtils; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.MultiStatus; import org.apache.jackrabbit.webdav.client.methods.OptionsMethod; import org.apache.jackrabbit.webdav.search.SearchInfo; import org.apache.jackrabbit.webdav.xml.Namespace; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; import java.io.IOException; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** * Remote operation performing the search in the Nextcloud server. */ public class SearchOperation extends RemoteOperation { private static final String HEADER_CONTENT_TYPE_VALUE = "text/xml"; private static final String DAV_NAMESPACE = "DAV:"; public enum SearchType { FILE_SEARCH, FAVORITE_SEARCH, CONTENT_TYPE_SEARCH } private String searchQuery; private String username; private SearchType searchType; public SearchOperation(String query, SearchType searchType, String username) { this.searchQuery = query; this.searchType = searchType; this.username = username; } @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; SearchMethod searchMethod = null; OptionsMethod optionsMethod = null; String webDavUrl = client.getWebdavUri().toString(); optionsMethod = new OptionsMethod(webDavUrl); try { int optionsStatus = client.executeMethod(optionsMethod); boolean isSearchSupported = optionsMethod.isAllowed("SEARCH"); if (isSearchSupported) { searchMethod = new SearchMethod(webDavUrl, new SearchInfo("NC", Namespace.XMLNS_NAMESPACE, "NC")); int status = client.executeMethod(searchMethod); // check and process response boolean isSuccess = ( status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK ); if (isSuccess) { // get data from remote folder MultiStatus dataInServer = searchMethod.getResponseBodyAsMultiStatus(); WebDavFileUtils webDavFileUtils = new WebDavFileUtils(); ArrayList<Object> mFolderAndFiles = webDavFileUtils.readData(dataInServer, client, false, true, username); // Result of the operation result = new RemoteOperationResult(true, status, searchMethod.getResponseHeaders()); // Add data to the result if (result.isSuccess()) { result.setData(mFolderAndFiles); } } else { // synchronization failed client.exhaustResponse(searchMethod.getResponseBodyAsStream()); result = new RemoteOperationResult(false, status, searchMethod.getResponseHeaders()); } } else { client.exhaustResponse(optionsMethod.getResponseBodyAsStream()); result = new RemoteOperationResult(false, optionsStatus, optionsMethod.getResponseHeaders()); } } catch (Exception e) { result = new RemoteOperationResult(e); } finally { if (searchMethod != null) { searchMethod.releaseConnection(); // let the connection available for other methods } if (optionsMethod != null) { optionsMethod.releaseConnection(); } } return result; } private class SearchMethod extends org.apache.jackrabbit.webdav.client.methods.SearchMethod { public SearchMethod(String uri, String statement, String language) throws IOException { super(uri, statement, language); } public SearchMethod(String uri, String statement, String language, Namespace languageNamespace) throws IOException { super(uri, statement, language, languageNamespace); } public SearchMethod(String uri, SearchInfo searchInfo) throws IOException { super(uri, searchInfo); setRequestHeader(HEADER_CONTENT_TYPE, HEADER_CONTENT_TYPE_VALUE); setRequestBody(createQuery(searchQuery, searchType)); } } private Document createQuery(String searchString, SearchType searchType) { if (searchType == SearchType.FAVORITE_SEARCH) { searchString = "yes"; } Document query; try { query = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException parserError) { System.err.println("ParserConfigurationException: " + parserError.getLocalizedMessage()); return null; } // Create Nodes & Elements Element searchRequestElement = query.createElementNS(DAV_NAMESPACE, "d:searchrequest"); Element basicSearchElement = query.createElementNS(DAV_NAMESPACE, "d:basicsearch"); Element selectElement = query.createElementNS(DAV_NAMESPACE, "d:select"); Element selectPropsElement = query.createElementNS(DAV_NAMESPACE, "d:prop"); // get all Element displayNameElement = query.createElementNS(DAV_NAMESPACE, "d:displayname"); Element contentTypeElement = query.createElementNS(DAV_NAMESPACE, "d:getcontenttype"); Element resourceTypeElement = query.createElementNS(DAV_NAMESPACE, "d:resourcetype"); Element contentLengthElement = query.createElementNS(DAV_NAMESPACE, "d:getcontentlength"); Element lastModifiedElement = query.createElementNS(DAV_NAMESPACE, "d:getlastmodified"); Element creationDate = query.createElementNS(DAV_NAMESPACE, "d:creationdate"); Element etagElement = query.createElementNS(DAV_NAMESPACE, "d:getetag"); Element quotaUsedElement = query.createElementNS(DAV_NAMESPACE, "d:quota-used-bytes"); Element quotaAvailableElement = query.createElementNS(DAV_NAMESPACE, "d:quota-available-bytes"); Element permissionsElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:permissions"); Element remoteIdElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:id"); Element sizeElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:size"); Element favoriteElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:favorite"); selectPropsElement.appendChild(displayNameElement); selectPropsElement.appendChild(contentTypeElement); selectPropsElement.appendChild(resourceTypeElement); selectPropsElement.appendChild(contentLengthElement); selectPropsElement.appendChild(lastModifiedElement); selectPropsElement.appendChild(creationDate); selectPropsElement.appendChild(etagElement); selectPropsElement.appendChild(quotaUsedElement); selectPropsElement.appendChild(quotaAvailableElement); selectPropsElement.appendChild(permissionsElement); selectPropsElement.appendChild(remoteIdElement); selectPropsElement.appendChild(sizeElement); selectPropsElement.appendChild(favoriteElement); Element fromElement = query.createElementNS(DAV_NAMESPACE, "d:from"); Element scopeElement = query.createElementNS(DAV_NAMESPACE, "d:scope"); Element hrefElement = query.createElementNS(DAV_NAMESPACE, "d:href"); Element depthElement = query.createElementNS(DAV_NAMESPACE, "d:depth"); Text hrefTextElement = query.createTextNode("/files/" + username); Text depthTextElement = query.createTextNode("infinity"); Element whereElement = query.createElementNS(DAV_NAMESPACE, "d:where"); Element equalsElement; if (searchType != SearchType.FAVORITE_SEARCH) { equalsElement = query.createElementNS(DAV_NAMESPACE, "d:like"); } else { equalsElement = query.createElementNS(DAV_NAMESPACE, "d:eq"); } Element propElement = query.createElementNS(DAV_NAMESPACE, "d:prop"); Element queryElement = null; if (searchType == SearchType.CONTENT_TYPE_SEARCH) { queryElement = query.createElementNS(DAV_NAMESPACE, "d:getcontenttype"); } else if (searchType == SearchType.FILE_SEARCH){ queryElement = query.createElementNS(DAV_NAMESPACE, "d:displayname"); } else { queryElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:favorite"); } Element literalElement = query.createElementNS(DAV_NAMESPACE, "d:literal"); Text literalTextElement = query.createTextNode(searchString); Element orderByElement = query.createElementNS(DAV_NAMESPACE, "d:orderby"); // Build XML tree searchRequestElement.setAttribute("xmlns:oc", "http://nextcloud.com/ns"); query.appendChild(searchRequestElement); searchRequestElement.appendChild(basicSearchElement); basicSearchElement.appendChild(selectElement); basicSearchElement.appendChild(fromElement); basicSearchElement.appendChild(whereElement); selectElement.appendChild(selectPropsElement); fromElement.appendChild(scopeElement); scopeElement.appendChild(hrefElement); scopeElement.appendChild(depthElement); hrefElement.appendChild(hrefTextElement); depthElement.appendChild(depthTextElement); whereElement.appendChild(equalsElement); equalsElement.appendChild(propElement); equalsElement.appendChild(literalElement); propElement.appendChild(queryElement); literalElement.appendChild(literalTextElement); basicSearchElement.appendChild(orderByElement); return query; } } Loading
src/com/owncloud/android/lib/common/utils/WebDavFileUtils.java 0 → 100644 +103 −0 Original line number Diff line number Diff line /** * Nextcloud Android client application * * @author Mario Danic * Copyright (C) 2017 Mario Danic * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.owncloud.android.lib.common.utils; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; import com.owncloud.android.lib.resources.files.RemoteFile; import org.apache.jackrabbit.webdav.MultiStatus; import java.util.ArrayList; /** * WebDav helper. */ public class WebDavFileUtils { /** * Read the data retrieved from the server about the contents of the target folder * * * @param remoteData Full response got from the server with the data of the target * folder and its direct children. * @param client Client instance to the remote server where the data were * retrieved. * @return */ public ArrayList<Object> readData(MultiStatus remoteData, OwnCloudClient client, boolean isReadFolderOperation, boolean isSearchOperation, String username) { ArrayList<Object> mFolderAndFiles = new ArrayList<Object>(); WebdavEntry we; int start = 1; if (isReadFolderOperation) { we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath()); mFolderAndFiles.add(fillOCFile(we)); } else { start = 0; } String stripString = client.getWebdavUri().getPath(); if (isSearchOperation && username != null) { stripString = stripString + "/files/" + username; } // loop to update every child RemoteFile remoteFile = null; for (int i = start; i < remoteData.getResponses().length; i++) { /// new OCFile instance with the data from the server we = new WebdavEntry(remoteData.getResponses()[i], stripString); remoteFile = fillOCFile(we); mFolderAndFiles.add(remoteFile); } return mFolderAndFiles; } /** * Creates and populates a new {@link RemoteFile} object with the data read from the server. * * @param we WebDAV entry read from the server for a WebDAV resource (remote file or folder). * @return New OCFile instance representing the remote resource described by we. */ private RemoteFile fillOCFile(WebdavEntry we) { RemoteFile file = new RemoteFile(we.decodedPath()); file.setCreationTimestamp(we.createTimestamp()); file.setLength(we.contentLength()); file.setMimeType(we.contentType()); file.setModifiedTimestamp(we.modifiedTimestamp()); file.setEtag(we.etag()); file.setPermissions(we.permissions()); file.setRemoteId(we.remoteId()); file.setSize(we.size()); file.setQuotaUsedBytes(we.quotaUsedBytes()); file.setQuotaAvailableBytes(we.quotaAvailableBytes()); file.setFavorite(we.isFavorite()); return file; } }
src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java +16 −14 Original line number Diff line number Diff line Loading @@ -24,6 +24,19 @@ package com.owncloud.android.lib.resources.files; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; Loading @@ -34,19 +47,6 @@ import java.util.Iterator; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; /** * Remote operation performing the download of a remote file in the ownCloud server. * Loading @@ -64,6 +64,8 @@ public class DownloadRemoteFileOperation extends RemoteOperation { private String mEtag = ""; private GetMethod mGet; private String mRemotePath; private String mLocalFolderPath; Loading
src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java +9 −37 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.common.utils.WebDavFileUtils; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavConstants; Loading @@ -50,7 +51,6 @@ public class ReadRemoteFolderOperation extends RemoteOperation { private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName(); private String mRemotePath; private ArrayList<Object> mFolderAndFiles; /** * Constructor Loading Loading @@ -86,7 +86,8 @@ public class ReadRemoteFolderOperation extends RemoteOperation { if (isSuccess) { // get data from remote folder MultiStatus dataInServer = query.getResponseBodyAsMultiStatus(); readData(dataInServer, client); WebDavFileUtils webDavFileUtils = new WebDavFileUtils(); ArrayList<Object> mFolderAndFiles = webDavFileUtils.readData(dataInServer, client, true, false, ""); // Result of the operation result = new RemoteOperationResult(true, status, query.getResponseHeaders()); Loading @@ -103,7 +104,6 @@ public class ReadRemoteFolderOperation extends RemoteOperation { } catch (Exception e) { result = new RemoteOperationResult(e); } finally { if (query != null) query.releaseConnection(); // let the connection available for other methods Loading @@ -126,34 +126,6 @@ public class ReadRemoteFolderOperation extends RemoteOperation { return (status == HttpStatus.SC_MULTI_STATUS); } /** * Read the data retrieved from the server about the contents of the target folder * * * @param remoteData Full response got from the server with the data of the target * folder and its direct children. * @param client Client instance to the remote server where the data were * retrieved. * @return */ private void readData(MultiStatus remoteData, OwnCloudClient client) { mFolderAndFiles = new ArrayList<Object>(); // parse data from remote folder WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath()); mFolderAndFiles.add(fillOCFile(we)); // loop to update every child RemoteFile remoteFile = null; for (int i = 1; i < remoteData.getResponses().length; ++i) { /// new OCFile instance with the data from the server we = new WebdavEntry(remoteData.getResponses()[i], client.getWebdavUri().getPath()); remoteFile = fillOCFile(we); mFolderAndFiles.add(remoteFile); } } /** * Creates and populates a new {@link RemoteFile} object with the data read from the server. Loading
src/com/owncloud/android/lib/resources/files/SearchOperation.java 0 → 100644 +248 −0 Original line number Diff line number Diff line /** * Nextcloud Android client application * * @author Mario Danic * Copyright (C) 2017 Mario Danic * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.owncloud.android.lib.resources.files; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.WebDavFileUtils; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.MultiStatus; import org.apache.jackrabbit.webdav.client.methods.OptionsMethod; import org.apache.jackrabbit.webdav.search.SearchInfo; import org.apache.jackrabbit.webdav.xml.Namespace; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; import java.io.IOException; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** * Remote operation performing the search in the Nextcloud server. */ public class SearchOperation extends RemoteOperation { private static final String HEADER_CONTENT_TYPE_VALUE = "text/xml"; private static final String DAV_NAMESPACE = "DAV:"; public enum SearchType { FILE_SEARCH, FAVORITE_SEARCH, CONTENT_TYPE_SEARCH } private String searchQuery; private String username; private SearchType searchType; public SearchOperation(String query, SearchType searchType, String username) { this.searchQuery = query; this.searchType = searchType; this.username = username; } @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; SearchMethod searchMethod = null; OptionsMethod optionsMethod = null; String webDavUrl = client.getWebdavUri().toString(); optionsMethod = new OptionsMethod(webDavUrl); try { int optionsStatus = client.executeMethod(optionsMethod); boolean isSearchSupported = optionsMethod.isAllowed("SEARCH"); if (isSearchSupported) { searchMethod = new SearchMethod(webDavUrl, new SearchInfo("NC", Namespace.XMLNS_NAMESPACE, "NC")); int status = client.executeMethod(searchMethod); // check and process response boolean isSuccess = ( status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK ); if (isSuccess) { // get data from remote folder MultiStatus dataInServer = searchMethod.getResponseBodyAsMultiStatus(); WebDavFileUtils webDavFileUtils = new WebDavFileUtils(); ArrayList<Object> mFolderAndFiles = webDavFileUtils.readData(dataInServer, client, false, true, username); // Result of the operation result = new RemoteOperationResult(true, status, searchMethod.getResponseHeaders()); // Add data to the result if (result.isSuccess()) { result.setData(mFolderAndFiles); } } else { // synchronization failed client.exhaustResponse(searchMethod.getResponseBodyAsStream()); result = new RemoteOperationResult(false, status, searchMethod.getResponseHeaders()); } } else { client.exhaustResponse(optionsMethod.getResponseBodyAsStream()); result = new RemoteOperationResult(false, optionsStatus, optionsMethod.getResponseHeaders()); } } catch (Exception e) { result = new RemoteOperationResult(e); } finally { if (searchMethod != null) { searchMethod.releaseConnection(); // let the connection available for other methods } if (optionsMethod != null) { optionsMethod.releaseConnection(); } } return result; } private class SearchMethod extends org.apache.jackrabbit.webdav.client.methods.SearchMethod { public SearchMethod(String uri, String statement, String language) throws IOException { super(uri, statement, language); } public SearchMethod(String uri, String statement, String language, Namespace languageNamespace) throws IOException { super(uri, statement, language, languageNamespace); } public SearchMethod(String uri, SearchInfo searchInfo) throws IOException { super(uri, searchInfo); setRequestHeader(HEADER_CONTENT_TYPE, HEADER_CONTENT_TYPE_VALUE); setRequestBody(createQuery(searchQuery, searchType)); } } private Document createQuery(String searchString, SearchType searchType) { if (searchType == SearchType.FAVORITE_SEARCH) { searchString = "yes"; } Document query; try { query = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException parserError) { System.err.println("ParserConfigurationException: " + parserError.getLocalizedMessage()); return null; } // Create Nodes & Elements Element searchRequestElement = query.createElementNS(DAV_NAMESPACE, "d:searchrequest"); Element basicSearchElement = query.createElementNS(DAV_NAMESPACE, "d:basicsearch"); Element selectElement = query.createElementNS(DAV_NAMESPACE, "d:select"); Element selectPropsElement = query.createElementNS(DAV_NAMESPACE, "d:prop"); // get all Element displayNameElement = query.createElementNS(DAV_NAMESPACE, "d:displayname"); Element contentTypeElement = query.createElementNS(DAV_NAMESPACE, "d:getcontenttype"); Element resourceTypeElement = query.createElementNS(DAV_NAMESPACE, "d:resourcetype"); Element contentLengthElement = query.createElementNS(DAV_NAMESPACE, "d:getcontentlength"); Element lastModifiedElement = query.createElementNS(DAV_NAMESPACE, "d:getlastmodified"); Element creationDate = query.createElementNS(DAV_NAMESPACE, "d:creationdate"); Element etagElement = query.createElementNS(DAV_NAMESPACE, "d:getetag"); Element quotaUsedElement = query.createElementNS(DAV_NAMESPACE, "d:quota-used-bytes"); Element quotaAvailableElement = query.createElementNS(DAV_NAMESPACE, "d:quota-available-bytes"); Element permissionsElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:permissions"); Element remoteIdElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:id"); Element sizeElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:size"); Element favoriteElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:favorite"); selectPropsElement.appendChild(displayNameElement); selectPropsElement.appendChild(contentTypeElement); selectPropsElement.appendChild(resourceTypeElement); selectPropsElement.appendChild(contentLengthElement); selectPropsElement.appendChild(lastModifiedElement); selectPropsElement.appendChild(creationDate); selectPropsElement.appendChild(etagElement); selectPropsElement.appendChild(quotaUsedElement); selectPropsElement.appendChild(quotaAvailableElement); selectPropsElement.appendChild(permissionsElement); selectPropsElement.appendChild(remoteIdElement); selectPropsElement.appendChild(sizeElement); selectPropsElement.appendChild(favoriteElement); Element fromElement = query.createElementNS(DAV_NAMESPACE, "d:from"); Element scopeElement = query.createElementNS(DAV_NAMESPACE, "d:scope"); Element hrefElement = query.createElementNS(DAV_NAMESPACE, "d:href"); Element depthElement = query.createElementNS(DAV_NAMESPACE, "d:depth"); Text hrefTextElement = query.createTextNode("/files/" + username); Text depthTextElement = query.createTextNode("infinity"); Element whereElement = query.createElementNS(DAV_NAMESPACE, "d:where"); Element equalsElement; if (searchType != SearchType.FAVORITE_SEARCH) { equalsElement = query.createElementNS(DAV_NAMESPACE, "d:like"); } else { equalsElement = query.createElementNS(DAV_NAMESPACE, "d:eq"); } Element propElement = query.createElementNS(DAV_NAMESPACE, "d:prop"); Element queryElement = null; if (searchType == SearchType.CONTENT_TYPE_SEARCH) { queryElement = query.createElementNS(DAV_NAMESPACE, "d:getcontenttype"); } else if (searchType == SearchType.FILE_SEARCH){ queryElement = query.createElementNS(DAV_NAMESPACE, "d:displayname"); } else { queryElement = query.createElementNS(WebdavEntry.NAMESPACE_OC, "oc:favorite"); } Element literalElement = query.createElementNS(DAV_NAMESPACE, "d:literal"); Text literalTextElement = query.createTextNode(searchString); Element orderByElement = query.createElementNS(DAV_NAMESPACE, "d:orderby"); // Build XML tree searchRequestElement.setAttribute("xmlns:oc", "http://nextcloud.com/ns"); query.appendChild(searchRequestElement); searchRequestElement.appendChild(basicSearchElement); basicSearchElement.appendChild(selectElement); basicSearchElement.appendChild(fromElement); basicSearchElement.appendChild(whereElement); selectElement.appendChild(selectPropsElement); fromElement.appendChild(scopeElement); scopeElement.appendChild(hrefElement); scopeElement.appendChild(depthElement); hrefElement.appendChild(hrefTextElement); depthElement.appendChild(depthTextElement); whereElement.appendChild(equalsElement); equalsElement.appendChild(propElement); equalsElement.appendChild(literalElement); propElement.appendChild(queryElement); literalElement.appendChild(literalTextElement); basicSearchElement.appendChild(orderByElement); return query; } }