diff --git a/.gitignore b/.gitignore
index 58eaa38..38e83a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
/.settings/
/.classpath
/.project
-*.iml
\ No newline at end of file
+*.iml
+.idea
\ No newline at end of file
diff --git a/runtime/config/PrivilegeRoles.xml b/runtime/config/PrivilegeRoles.xml
index ce63b78..09a437f 100644
--- a/runtime/config/PrivilegeRoles.xml
+++ b/runtime/config/PrivilegeRoles.xml
@@ -1,180 +1,183 @@
-
-
- li.strolch.bookshop.service.CreateBookService
- li.strolch.bookshop.service.UpdateBookService
- li.strolch.bookshop.service.RemoveBookService
-
-
- internal
- li.strolch.bookshop.query.BooksQuery
-
+
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
+
+ li.strolch.bookshop.service.CreateBookService
+ li.strolch.bookshop.service.UpdateBookService
+ li.strolch.bookshop.service.RemoveBookService
+
-
-
-
-
+
+ internal
+ li.strolch.bookshop.search.BookSearch
+
-
-
-
- true
-
-
- true
-
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
+
+
+
+
-
- true
-
-
- true
-
-
+
+
+
+ true
+
-
-
- li.strolch.runtime.privilege.StrolchSystemAction
- li.strolch.runtime.privilege.StrolchSystemActionWithResult
- li.strolch.persistence.postgresql.PostgreSqlSchemaInitializer
-
-
- true
-
+
+ true
+
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
-
- true
-
-
- Persist
- PersistSessions
- GetCertificates
-
-
- true
-
-
- true
-
-
- true
-
-
+
+ true
+
+
+ true
+
+
+
+
+
+ li.strolch.runtime.privilege.StrolchSystemAction
+ li.strolch.runtime.privilege.StrolchSystemActionWithResult
+ li.strolch.persistence.postgresql.PostgreSqlSchemaInitializer
+
+
+ true
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ true
+
+
+ Persist
+ PersistSessions
+ GetCertificates
+
+
+ true
+
+
+ true
+
+
+ true
+
+
diff --git a/src/main/java/li/strolch/bookshop/query/BooksQuery.java b/src/main/java/li/strolch/bookshop/query/BooksQuery.java
deleted file mode 100644
index f1d646f..0000000
--- a/src/main/java/li/strolch/bookshop/query/BooksQuery.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package li.strolch.bookshop.query;
-
-import li.strolch.bookshop.BookShopConstants;
-import li.strolch.model.query.ResourceQuery;
-import li.strolch.model.query.StrolchTypeNavigation;
-
-public class BooksQuery extends ResourceQuery {
-
- public BooksQuery() {
- super(new StrolchTypeNavigation(BookShopConstants.TYPE_BOOK));
- }
-}
diff --git a/src/main/java/li/strolch/bookshop/rest/BooksResource.java b/src/main/java/li/strolch/bookshop/rest/BooksResource.java
index 50e313d..2603309 100644
--- a/src/main/java/li/strolch/bookshop/rest/BooksResource.java
+++ b/src/main/java/li/strolch/bookshop/rest/BooksResource.java
@@ -6,21 +6,16 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
-import java.util.List;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import li.strolch.bookshop.BookShopConstants;
-import li.strolch.bookshop.query.BooksQuery;
+import li.strolch.bookshop.search.BookSearch;
import li.strolch.bookshop.service.CreateBookService;
import li.strolch.bookshop.service.RemoveBookService;
import li.strolch.bookshop.service.UpdateBookService;
import li.strolch.model.Resource;
import li.strolch.model.json.StrolchRootElementToJsonVisitor;
-import li.strolch.model.query.NameSelection;
-import li.strolch.model.query.OrSelection;
-import li.strolch.model.query.ParameterSelection;
-import li.strolch.model.query.ResourceQuery;
import li.strolch.model.visitor.ResourceVisitor;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.model.Certificate;
@@ -32,7 +27,6 @@ import li.strolch.service.JsonServiceResult;
import li.strolch.service.StringServiceArgument;
import li.strolch.service.api.ServiceHandler;
import li.strolch.service.api.ServiceResult;
-import li.strolch.utils.StringMatchMode;
import li.strolch.utils.collections.Paging;
import li.strolch.utils.helper.StringHelper;
@@ -51,36 +45,19 @@ public class BooksResource {
int limit = StringHelper.isNotEmpty(limitS) ? Integer.valueOf(limitS) : 20;
// open the TX with the certificate, using this class as context
+ Paging paging;
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getClass())) {
- // prepare the query
- ResourceQuery query = new BooksQuery<>();
-
- // prepare selections
- if (StringHelper.isEmpty(queryS)) {
- query.withAny();
- } else {
- OrSelection or = new OrSelection();
- or.with(ParameterSelection
- .stringSelection(BookShopConstants.BAG_PARAMETERS, BookShopConstants.PARAM_DESCRIPTION, queryS,
- StringMatchMode.ci()));
- or.with(new NameSelection(queryS, StringMatchMode.ci()));
-
- // add selections
- query.with(or);
- }
-
- // perform the query
- List books = tx.doQuery(query);
-
- // perform paging
- Paging paging = Paging.asPage(books, offset, limit);
- List page = paging.getPage();
-
- // return result, transforming to JSON
- ResourceVisitor visitor = new StrolchRootElementToJsonVisitor().flat().asResourceVisitor();
- return ResponseUtil.listToResponse(StrolchRestfulConstants.DATA, page, a -> a.accept(visitor));
+ // perform a book search
+ paging = new BookSearch() //
+ .stringQuery(queryS) //
+ .search(tx) //
+ .orderByName(false) //
+ .toPaging(offset, limit);
}
+
+ ResourceVisitor visitor = new StrolchRootElementToJsonVisitor().flat().asResourceVisitor();
+ return ResponseUtil.toResponse(paging, e -> e.accept(visitor));
}
@GET
diff --git a/src/main/java/li/strolch/bookshop/search/BookSearch.java b/src/main/java/li/strolch/bookshop/search/BookSearch.java
new file mode 100644
index 0000000..be685df
--- /dev/null
+++ b/src/main/java/li/strolch/bookshop/search/BookSearch.java
@@ -0,0 +1,29 @@
+package li.strolch.bookshop.search;
+
+import static li.strolch.bookshop.BookShopConstants.*;
+import static li.strolch.utils.helper.StringHelper.isEmpty;
+
+import li.strolch.search.ResourceSearch;
+
+public class BookSearch extends ResourceSearch {
+
+ public BookSearch() {
+ types(TYPE_BOOK);
+ }
+
+ public BookSearch stringQuery(String value) {
+ if (isEmpty(value))
+ return this;
+
+ // split by spaces
+ value = value.trim();
+ String[] values = value.split(" ");
+
+ // add where clauses for id, name and description
+ where(id().containsIgnoreCase(values) //
+ .or(name().containsIgnoreCase(values)) //
+ .or(param(BAG_PARAMETERS, PARAM_DESCRIPTION).containsIgnoreCase(values)));
+
+ return this;
+ }
+}
diff --git a/src/main/java/li/strolch/bookshop/web/StartupListener.java b/src/main/java/li/strolch/bookshop/web/StartupListener.java
index fc686bf..ef1be76 100644
--- a/src/main/java/li/strolch/bookshop/web/StartupListener.java
+++ b/src/main/java/li/strolch/bookshop/web/StartupListener.java
@@ -1,56 +1,57 @@
package li.strolch.bookshop.web;
-import java.io.InputStream;
-
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.InputStream;
import li.strolch.agent.api.StrolchAgent;
import li.strolch.agent.api.StrolchBootstrapper;
import li.strolch.utils.helper.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@WebListener
public class StartupListener implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(StartupListener.class);
+ private static final String APP_NAME = "Bookshop";
private StrolchAgent agent;
@Override
public void contextInitialized(ServletContextEvent sce) {
- logger.info("Starting Bookshop...");
+ logger.info("Starting " + APP_NAME + "...");
long start = System.currentTimeMillis();
try {
- // we load the configuration by reading the boot strap file:
String boostrapFileName = "/WEB-INF/" + StrolchBootstrapper.FILE_BOOTSTRAP;
InputStream bootstrapFile = sce.getServletContext().getResourceAsStream(boostrapFileName);
StrolchBootstrapper bootstrapper = new StrolchBootstrapper(StartupListener.class);
-
- // now setup, initialize and start Strolch:
this.agent = bootstrapper.setupByBoostrapFile(StartupListener.class, bootstrapFile);
this.agent.initialize();
this.agent.start();
-
- } catch (Exception e) {
- logger.error("Failed to start Bookshop due to: " + e.getMessage(), e);
+ } catch (Throwable e) {
+ logger.error("Failed to start " + APP_NAME + " due to: " + e.getMessage(), e);
throw e;
}
long took = System.currentTimeMillis() - start;
- logger.info("Started Bookshop in " + (StringHelper.formatMillisecondsDuration(took)));
+ logger.info("Started " + APP_NAME + " in " + (StringHelper.formatMillisecondsDuration(took)));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
if (this.agent != null) {
- this.agent.stop();
- this.agent.destroy();
+ logger.info("Destroying " + APP_NAME + "...");
+ try {
+ this.agent.stop();
+ this.agent.destroy();
+ } catch (Throwable e) {
+ logger.error("Failed to stop " + APP_NAME + " due to: " + e.getMessage(), e);
+ throw e;
+ }
}
- logger.info("Destroyed Bookshop.");
+ logger.info("Destroyed " + APP_NAME);
}
}
diff --git a/src/main/webapp/WEB-INF/StrolchBootstrap.xml b/src/main/webapp/WEB-INF/StrolchBootstrap.xml
index 1364aa0..2e21dd6 100644
--- a/src/main/webapp/WEB-INF/StrolchBootstrap.xml
+++ b/src/main/webapp/WEB-INF/StrolchBootstrap.xml
@@ -5,9 +5,5 @@
/home/eitch/src/git/strolch-bookshop/runtime
dev
-
- /Users/eitch/src/git/strolch-bookshop/runtime
- dev
-
-
+
\ No newline at end of file