diff --git a/client/package.json b/client/package.json
index 5e1c0c1..e0b5ce0 100644
--- a/client/package.json
+++ b/client/package.json
@@ -37,13 +37,13 @@
"@angular/platform-browser": "^8.2.4",
"@angular/platform-browser-dynamic": "^8.2.4",
"@angular/router": "^8.2.4",
- "@groupdocs.examples.angular/annotation": "^0.6.1",
- "@groupdocs.examples.angular/comparison": "^0.6.1",
- "@groupdocs.examples.angular/conversion": "^0.6.1",
- "@groupdocs.examples.angular/editor": "^0.6.1",
- "@groupdocs.examples.angular/signature": "^0.6.1",
- "@groupdocs.examples.angular/viewer": "^0.6.1",
- "@nrwl/angular": "^8.12.6",
+ "@groupdocs.examples.angular/annotation": "^0.6.3",
+ "@groupdocs.examples.angular/comparison": "^0.6.3",
+ "@groupdocs.examples.angular/conversion": "^0.6.3",
+ "@groupdocs.examples.angular/editor": "^0.6.3",
+ "@groupdocs.examples.angular/signature": "^0.6.3",
+ "@groupdocs.examples.angular/viewer": "^0.6.3",
+ "@nrwl/angular": "^8.12.7",
"common-components": "^1.0.5",
"core-js": "^2.6.11",
"rxjs": "~6.4.0",
diff --git a/configuration.yml b/configuration.yml
index dce221f..3f7eab7 100644
--- a/configuration.yml
+++ b/configuration.yml
@@ -218,4 +218,18 @@ editor:
# Absolute path to default document
defaultDocument:
# Enable / disable new document creation
- createNewFile: true
\ No newline at end of file
+ createNewFile: true
+
+################################################
+# GroupDocs.Search configurations
+################################################
+search:
+ # Files directory path
+ # Absolute or relative path to files directory
+ filesDirectory: DocumentSamples/Search
+ # Fonts path
+ # Absolute path to custom fonts directory
+ fontsDirectory:
+ # Default document
+ # Absolute path to default document
+ defaultDocument:
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 585d502..26a80c1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -147,6 +147,11 @@
19.7
jar
+
+ com.groupdocs
+ groupdocs-search
+ 19.12
+
com.groupdocs
groupdocs-viewer
diff --git a/src/main/java/com/groupdocs/ui/config/DefaultDirectories.java b/src/main/java/com/groupdocs/ui/config/DefaultDirectories.java
index d17e60f..e17787e 100644
--- a/src/main/java/com/groupdocs/ui/config/DefaultDirectories.java
+++ b/src/main/java/com/groupdocs/ui/config/DefaultDirectories.java
@@ -20,6 +20,7 @@ public class DefaultDirectories {
public static final String ANNOTATION = "Annotation";
public static final String CONVERSION = "Conversion";
public static final String EDITOR = "Editor";
+ public static final String SEARCH = "Search";
public static String defaultLicenseDirectory() {
Path defaultLicFolder = FileSystems.getDefault().getPath(LICENSES).toAbsolutePath();
@@ -57,6 +58,10 @@ public static String defaultEditorDirectory() {
return getDefaultFilesDir(EDITOR);
}
+ public static String defaultSearchDirectory() {
+ return getDefaultFilesDir(SEARCH);
+ }
+
public static String getDefaultFilesDir(String folder) {
String dir = DOCUMENT_SAMPLES + File.separator + folder;
Path path = FileSystems.getDefault().getPath(dir).toAbsolutePath();
diff --git a/src/main/java/com/groupdocs/ui/search/config/SearchConfiguration.java b/src/main/java/com/groupdocs/ui/search/config/SearchConfiguration.java
new file mode 100644
index 0000000..b2203c9
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/config/SearchConfiguration.java
@@ -0,0 +1,62 @@
+package com.groupdocs.ui.search.config;
+
+import com.groupdocs.ui.config.CommonConfiguration;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.PostConstruct;
+
+import static com.groupdocs.ui.config.DefaultDirectories.*;
+
+@Component
+public class SearchConfiguration extends CommonConfiguration {
+
+ @Value("${search.filesDirectory}")
+ private String filesDirectory;
+
+ @Value("${search.defaultDocument}")
+ private String defaultDocument;
+
+ @Value("${search.fontsDirectory}")
+ private String fontsDirectory;
+
+ @PostConstruct
+ public void init() {
+ this.filesDirectory = StringUtils.isEmpty(this.filesDirectory) ? defaultSearchDirectory() : relativePathToAbsolute(this.filesDirectory);
+ }
+
+ public String getFilesDirectory() {
+ return filesDirectory;
+ }
+
+ public void setFilesDirectory(String filesDirectory) {
+ this.filesDirectory = filesDirectory;
+ }
+
+ public String getDefaultDocument() {
+ return defaultDocument;
+ }
+
+ public void setDefaultDocument(String defaultDocument) {
+ this.defaultDocument = defaultDocument;
+ }
+
+ public String getFontsDirectory() {
+ return fontsDirectory;
+ }
+
+ public void setFontsDirectory(String fontsDirectory) {
+ this.fontsDirectory = fontsDirectory;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() +
+ "SearchConfiguration{" +
+ "filesDirectory='" + filesDirectory + '\'' +
+ ", defaultDocument='" + defaultDocument + '\'' +
+ ", fontsDirectory='" + fontsDirectory + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/java/com/groupdocs/ui/search/controller/SearchController.java b/src/main/java/com/groupdocs/ui/search/controller/SearchController.java
new file mode 100644
index 0000000..d31db73
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/controller/SearchController.java
@@ -0,0 +1,104 @@
+package com.groupdocs.ui.search.controller;
+
+import com.groupdocs.ui.model.request.FileTreeRequest;
+import com.groupdocs.ui.model.request.LoadDocumentRequest;
+import com.groupdocs.ui.model.response.FileDescriptionEntity;
+import com.groupdocs.ui.model.response.UploadedDocumentEntity;
+import com.groupdocs.ui.search.config.SearchConfiguration;
+import com.groupdocs.ui.search.model.IndexDocumentResult;
+import com.groupdocs.ui.search.model.SearchDocumentResult;
+import com.groupdocs.ui.search.model.SearchRequest;
+import com.groupdocs.ui.search.service.SearchService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+import static com.groupdocs.ui.util.Utils.uploadFile;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
+
+/**
+ * SearchController
+ *
+ * @author Aspose Pty Ltd
+ */
+@Controller
+@RequestMapping(value = "/search")
+public class SearchController {
+ private static final Logger logger = LoggerFactory.getLogger(SearchController.class);
+
+ private SearchService searchService;
+
+ public SearchController(@Autowired SearchService searchService) {
+ this.searchService = searchService;
+ }
+
+ @RequestMapping(method = RequestMethod.GET, value = "/loadConfig", produces = APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public SearchConfiguration loadConfig() {
+ return searchService.getSearchConfiguration();
+ }
+
+ /**
+ * Get files and directories
+ *
+ * @param fileTreeRequest request's object with specified path
+ * @return files and directories list
+ */
+ @RequestMapping(value = "/loadFileTree", method = RequestMethod.POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public List loadFileTree(@RequestBody FileTreeRequest fileTreeRequest) {
+ return searchService.getFileList(fileTreeRequest);
+ }
+
+ /**
+ * Get document description
+ *
+ * @return document description
+ */
+ @RequestMapping(value = "/loadDocumentDescription", method = RequestMethod.POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public IndexDocumentResult loadDocumentDescription(@RequestBody LoadDocumentRequest loadDocumentRequest) {
+ return searchService.getDocumentDescription(loadDocumentRequest);
+ }
+
+ /**
+ * Get document description
+ *
+ * @return document description
+ */
+ @RequestMapping(value = "/search", method = RequestMethod.POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public List loadDocumentDescription(@RequestBody SearchRequest searchRequest) {
+ return searchService.search(searchRequest);
+ }
+
+ /**
+ * Upload document
+ *
+ * @param content file data
+ * @param url url for document
+ * @param rewrite flag for rewriting file
+ * @return uploaded document object (the object contains uploaded document guid)
+ */
+ @RequestMapping(value = "/uploadDocument", method = RequestMethod.POST, produces = APPLICATION_JSON_VALUE, consumes = MULTIPART_FORM_DATA_VALUE)
+ @ResponseBody
+ public UploadedDocumentEntity uploadDocument(@Nullable @RequestParam("file") MultipartFile content,
+ @RequestParam(value = "url", required = false) String url,
+ @RequestParam("rewrite") Boolean rewrite) {
+ // get documents storage path
+ String documentStoragePath = searchService.getSearchConfiguration().getFilesDirectory();
+ // save the file
+ String pathname = uploadFile(documentStoragePath, content, url, rewrite);
+ // create response data
+ UploadedDocumentEntity uploadedDocument = new UploadedDocumentEntity();
+ uploadedDocument.setGuid(pathname);
+ return uploadedDocument;
+ }
+}
diff --git a/src/main/java/com/groupdocs/ui/search/model/IndexDocumentResult.java b/src/main/java/com/groupdocs/ui/search/model/IndexDocumentResult.java
new file mode 100644
index 0000000..af34df8
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/model/IndexDocumentResult.java
@@ -0,0 +1,16 @@
+package com.groupdocs.ui.search.model;
+
+import com.groupdocs.ui.model.response.LoadDocumentEntity;
+
+public class IndexDocumentResult extends LoadDocumentEntity {
+
+ private String indexStatus;
+
+ public String getIndexStatus() {
+ return indexStatus;
+ }
+
+ public void setIndexStatus(String indexStatus) {
+ this.indexStatus = indexStatus;
+ }
+}
diff --git a/src/main/java/com/groupdocs/ui/search/model/SearchDocumentResult.java b/src/main/java/com/groupdocs/ui/search/model/SearchDocumentResult.java
new file mode 100644
index 0000000..6043316
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/model/SearchDocumentResult.java
@@ -0,0 +1,25 @@
+package com.groupdocs.ui.search.model;
+
+import com.groupdocs.search.results.FoundDocumentField;
+
+public class SearchDocumentResult {
+
+ private FoundDocumentField[] foundFields;
+ private String filePath;
+
+ public void setFoundFields(FoundDocumentField[] foundFields) {
+ this.foundFields = foundFields;
+ }
+
+ public FoundDocumentField[] getFoundFields() {
+ return foundFields;
+ }
+
+ public void setFilePath(String filePath) {
+ this.filePath = filePath;
+ }
+
+ public String getFilePath() {
+ return filePath;
+ }
+}
diff --git a/src/main/java/com/groupdocs/ui/search/model/SearchRequest.java b/src/main/java/com/groupdocs/ui/search/model/SearchRequest.java
new file mode 100644
index 0000000..7092588
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/model/SearchRequest.java
@@ -0,0 +1,22 @@
+package com.groupdocs.ui.search.model;
+
+public class SearchRequest {
+ private String query;
+ private String[] guids;
+
+ public String getQuery() {
+ return query;
+ }
+
+ public void setQuery(String query) {
+ this.query = query;
+ }
+
+ public String[] getGuids() {
+ return guids;
+ }
+
+ public void setGuids(String[] guids) {
+ this.guids = guids;
+ }
+}
diff --git a/src/main/java/com/groupdocs/ui/search/service/SearchService.java b/src/main/java/com/groupdocs/ui/search/service/SearchService.java
new file mode 100644
index 0000000..2400a41
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/service/SearchService.java
@@ -0,0 +1,21 @@
+package com.groupdocs.ui.search.service;
+
+import com.groupdocs.ui.model.request.FileTreeRequest;
+import com.groupdocs.ui.model.request.LoadDocumentRequest;
+import com.groupdocs.ui.model.response.FileDescriptionEntity;
+import com.groupdocs.ui.search.config.SearchConfiguration;
+import com.groupdocs.ui.search.model.IndexDocumentResult;
+import com.groupdocs.ui.search.model.SearchDocumentResult;
+import com.groupdocs.ui.search.model.SearchRequest;
+
+import java.util.List;
+
+public interface SearchService {
+ SearchConfiguration getSearchConfiguration();
+
+ List getFileList(FileTreeRequest fileTreeRequest);
+
+ IndexDocumentResult getDocumentDescription(LoadDocumentRequest loadDocumentRequest);
+
+ List search(SearchRequest searchRequest);
+}
diff --git a/src/main/java/com/groupdocs/ui/search/service/SearchServiceImpl.java b/src/main/java/com/groupdocs/ui/search/service/SearchServiceImpl.java
new file mode 100644
index 0000000..1bfb70d
--- /dev/null
+++ b/src/main/java/com/groupdocs/ui/search/service/SearchServiceImpl.java
@@ -0,0 +1,151 @@
+package com.groupdocs.ui.search.service;
+
+import com.groupdocs.search.Index;
+import com.groupdocs.search.common.IndexStatus;
+import com.groupdocs.search.licensing.License;
+import com.groupdocs.search.results.FoundDocument;
+import com.groupdocs.search.results.SearchResult;
+import com.groupdocs.ui.config.GlobalConfiguration;
+import com.groupdocs.ui.exception.TotalGroupDocsException;
+import com.groupdocs.ui.model.request.FileTreeRequest;
+import com.groupdocs.ui.model.request.LoadDocumentRequest;
+import com.groupdocs.ui.model.response.FileDescriptionEntity;
+import com.groupdocs.ui.search.config.SearchConfiguration;
+import com.groupdocs.ui.search.model.IndexDocumentResult;
+import com.groupdocs.ui.search.model.SearchDocumentResult;
+import com.groupdocs.ui.search.model.SearchRequest;
+import org.apache.commons.io.FilenameUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.PostConstruct;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+@Service
+public class SearchServiceImpl implements SearchService {
+ private static final Logger logger = LoggerFactory.getLogger(SearchServiceImpl.class);
+
+ private final GlobalConfiguration globalConfiguration;
+
+ private final SearchConfiguration searchConfiguration;
+
+ public SearchServiceImpl(GlobalConfiguration globalConfiguration, SearchConfiguration searchConfiguration) {
+ this.globalConfiguration = globalConfiguration;
+ this.searchConfiguration = searchConfiguration;
+ }
+
+ @PostConstruct
+ public void init() {
+ try {
+ // set GroupDocs license
+ License license = new License();
+ license.setLicense(globalConfiguration.getApplication().getLicensePath());
+ } catch (Throwable exc) {
+ logger.error("Can not verify Search license!");
+ }
+ }
+
+ @Override
+ public SearchConfiguration getSearchConfiguration() {
+ return searchConfiguration;
+ }
+
+ @Override
+ public List getFileList(FileTreeRequest fileTreeRequest) {
+ String path = fileTreeRequest.getPath();
+ if (StringUtils.isEmpty(path)) {
+ path = searchConfiguration.getFilesDirectory();
+ }
+ try {
+ File directory = new File(path);
+ List filesList = Arrays.asList(directory.listFiles());
+ List fileList = getFileDescriptionEntities(filesList);
+ return fileList;
+ } catch (Exception ex) {
+ logger.error("Exception in getting file list", ex);
+ throw new TotalGroupDocsException(ex.getMessage(), ex);
+ }
+ }
+
+ @Override
+ public IndexDocumentResult getDocumentDescription(LoadDocumentRequest loadDocumentRequest) {
+ Index index = new Index(searchConfiguration.getFilesDirectory());
+
+ index.add(loadDocumentRequest.getGuid());
+
+ int indexStatus = index.getIndexInfo().getIndexStatus();
+
+ IndexDocumentResult searchDocumentResult = new IndexDocumentResult();
+ searchDocumentResult.setGuid(loadDocumentRequest.getGuid());
+ searchDocumentResult.setIndexStatus(getStatus(indexStatus));
+
+ return searchDocumentResult;
+ }
+
+ @Override
+ public List search(SearchRequest searchRequest) {
+ Index index = new Index(searchConfiguration.getFilesDirectory());
+
+ index.add(searchRequest.getGuids());
+
+ int indexStatus = index.getIndexInfo().getIndexStatus();
+
+ List results = new ArrayList<>();
+ if (IndexStatus.Ready == indexStatus) {
+ SearchResult search = index.search(searchRequest.getQuery());
+
+ Iterator iterator = search.iterator();
+ while (iterator.hasNext()) {
+ FoundDocument next = iterator.next();
+ SearchDocumentResult searchDocumentResult = new SearchDocumentResult();
+ searchDocumentResult.setFoundFields(next.getFoundFields());
+ searchDocumentResult.setFilePath(next.getDocumentInfo().getFilePath());
+
+ results.add(searchDocumentResult);
+ }
+ }
+
+ return results;
+ }
+
+ private String getStatus(int indexStatus) {
+ switch (indexStatus) {
+ case IndexStatus.NotStarted:
+ return "NotStarted";
+ case IndexStatus.Failed:
+ return "Failed";
+ case IndexStatus.InProgress:
+ return "InProgress";
+ case IndexStatus.LicenseRestrictionFinished:
+ return "LicenseRestrictionFinished";
+ case IndexStatus.Ready:
+ return "Ready";
+ default:
+ return "";
+ }
+ }
+
+ private List getFileDescriptionEntities(List filesList) {
+ List fileList = new ArrayList<>();
+ for (File file : filesList) {
+ String guid = file.getAbsolutePath();
+ String extension = FilenameUtils.getExtension(guid);
+ if (file.isDirectory() || !StringUtils.isEmpty(extension)) {
+ FileDescriptionEntity fileDescription = new FileDescriptionEntity();
+ fileDescription.setGuid(guid);
+ fileDescription.setName(file.getName());
+ fileDescription.setDirectory(file.isDirectory());
+ fileDescription.setSize(file.length());
+ fileList.add(fileDescription);
+ }
+ }
+ return fileList;
+ }
+
+}