Implementováno fulltextové vyhledávání přes všechny záznamy. Nutno
dořešit konfiguraci adresáře pro ukládání fulltextového indexu.
This commit is contained in:
@@ -14,6 +14,7 @@ import info.bukova.isspst.data.TripBill;
|
||||
import info.bukova.isspst.data.TripRequirement;
|
||||
import info.bukova.isspst.reporting.Report;
|
||||
import info.bukova.isspst.reporting.ReportMapping;
|
||||
import info.bukova.isspst.services.FullTextService;
|
||||
import info.bukova.isspst.services.addressbook.AdbService;
|
||||
import info.bukova.isspst.services.buildings.BuildingService;
|
||||
import info.bukova.isspst.services.invoicing.InvoicingService;
|
||||
@@ -81,6 +82,7 @@ public class Constants {
|
||||
public final static String MOD_APPROVED = "APPROVED";
|
||||
public final static String MOD_ORDER = "ORDER";
|
||||
public final static String MOD_INVOICING = "INVOICING";
|
||||
public final static String MOD_SEARCH = "SEARCH";
|
||||
public final static Module MODULES[] = {
|
||||
new Module(MOD_USERS, "Uživatelé", UserService.class),
|
||||
new Module(MOD_PERMISSIONS, "Práva", RoleService.class),
|
||||
@@ -96,7 +98,9 @@ public class Constants {
|
||||
new Module(MOD_TRIPBILL, "Cestovní příkazy", TripBillService.class),
|
||||
new Module(MOD_APPROVED, "Schválené položky požadavků", ApprovedService.class),
|
||||
new Module(MOD_ORDER, "Objednávky", OrderService.class),
|
||||
new Module(MOD_INVOICING, "Fakturace požadavků", InvoicingService.class) };
|
||||
new Module(MOD_INVOICING, "Fakturace požadavků", InvoicingService.class),
|
||||
new Module(MOD_SEARCH, "Fulltextové vyhledávání", FullTextService.class, true, false),
|
||||
};
|
||||
|
||||
public final static String PERM_APPROVE = "PERM_APPROVE";
|
||||
public final static String PERM_SHOW_WORKGROUP_REQ = "PERM_SHOW_WORKGROUP_REQ";
|
||||
@@ -104,6 +108,7 @@ public class Constants {
|
||||
public final static String PERM_SHOW_ALL_REQ = "PERM_SHOW_ALL_REQ";
|
||||
public final static String PERM_EDIT_NEW = "PERM_EDIT_NEW";
|
||||
public final static String PERM_EDIT_OWN = "PERM_EDIT_OWN";
|
||||
public final static String PERM_SEARCH = "PERM_SEARCH";
|
||||
|
||||
public final static Permission SPECIAL_PERMISSIONS[] = {
|
||||
new Permission(PERM_EDIT_NEW, "Upravit neschválené", MOD_REQUIREMENTS, PermissionType.GLOBAL),
|
||||
@@ -117,6 +122,8 @@ public class Constants {
|
||||
new Permission(PERM_SHOW_CENTRE_REQ, "Zobrazení požadavků střediska", MOD_TRIPREQUIREMENTS, PermissionType.CENTRE),
|
||||
new Permission(PERM_SHOW_ALL_REQ, "Zobrazení všech požadavků", MOD_TRIPREQUIREMENTS, PermissionType.GLOBAL),
|
||||
new Permission(PERM_APPROVE, "Schválení", MOD_TRIPREQUIREMENTS, PermissionType.WORKGROUP),
|
||||
|
||||
new Permission(PERM_SEARCH, "Vyhledávat", MOD_SEARCH, PermissionType.GLOBAL),
|
||||
};
|
||||
|
||||
public final static String DYNAMIC_REPORT_NAME = "Tabulková sestava";
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
package info.bukova.isspst;
|
||||
|
||||
import info.bukova.isspst.reporting.Report;
|
||||
import info.bukova.isspst.services.AbstractService;
|
||||
import info.bukova.isspst.services.ModuleNotActiveException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Třída reprezentuje informace o modulu (agendě).
|
||||
*
|
||||
*/
|
||||
public class Module {
|
||||
|
||||
private String id;
|
||||
@@ -22,6 +30,12 @@ public class Module {
|
||||
this.serviceClass = serviceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id identifikátor modulu
|
||||
* @param name jméno zobrazované v aplikaci
|
||||
* @param serviceClass servisní třída
|
||||
*/
|
||||
public Module(String id, String name, Class<?> serviceClass) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
@@ -31,11 +45,24 @@ public class Module {
|
||||
active = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id identifikátor modulu
|
||||
* @param name jméno zobrazované v aplikaci
|
||||
* @param serviceClass servisní třída
|
||||
* @param active příznak, jestli je modul aktivní
|
||||
*/
|
||||
public Module(String id, String name, Class<?> serviceClass, boolean active) {
|
||||
this(id, name, serviceClass);
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id identifikátor modulu
|
||||
* @param name jméno zobrazované v aplikaci
|
||||
* @param serviceClass servisní třída
|
||||
* @param active příznak, jestli je modul aktivní.
|
||||
* @param defaultPermissions příznak určující jestli modul kontroluje výchozí práva (čtení, zápis, modifikace, mazání)
|
||||
*/
|
||||
public Module(String id, String name, Class<?> serviceClass, boolean active, boolean defaultPermissions) {
|
||||
this(id, name, serviceClass, active);
|
||||
this.defaultPermissions = defaultPermissions;
|
||||
@@ -65,6 +92,12 @@ public class Module {
|
||||
this.reports.add(report);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pokud je true, modul kontroluje výchozí práva (čtení, zápis, modifikace, mazání). Má vliv
|
||||
* na generování formulářů v nastavení práv.
|
||||
*
|
||||
* @return výchozí práva. Default true
|
||||
*/
|
||||
public boolean isDefaultPermissions() {
|
||||
return defaultPermissions;
|
||||
}
|
||||
@@ -73,6 +106,13 @@ public class Module {
|
||||
this.defaultPermissions = defaultPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Určuje, zda je modul aktivní. Neaktivní moduly nejsou viditelné v UI. Při pokusu o přístup přímo přes URL
|
||||
* se generuje výjimka {@link ModuleNotActiveException}. Pokud servisní třída modulu nedědí z {@link AbstractService},
|
||||
* musí se implementovat kontrola aktivity do příslušné třídy.
|
||||
*
|
||||
* @return aktivita. Default true
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,41 @@ package info.bukova.isspst.services;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.search.annotations.Field;
|
||||
import org.hibernate.search.annotations.Indexed;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Rozhraní služby fulltextového vyhledávání
|
||||
*
|
||||
*/
|
||||
public interface FullTextService {
|
||||
|
||||
/**
|
||||
* Přegeneruje fulltextový index.
|
||||
*/
|
||||
public void reindex();
|
||||
|
||||
|
||||
/**
|
||||
* Vyhledává entity zadané třídy. Třída entity musí být anotovaná {@link Indexed}
|
||||
*
|
||||
* @param entityClass třída entity k vyhledání
|
||||
* @param fields property entity kde se bude vyhledávat. Musí být anotované {@link Field}
|
||||
* @param word vyhledávaný výraz
|
||||
* @return list odpovídajících entit
|
||||
*/
|
||||
public List<?> search(Class<?> entityClass, String[] fields, String word);
|
||||
|
||||
|
||||
/**
|
||||
* Globální vyhledávání ve všech entitách, jejichš třídy jsou anotované {@link Indexed} a
|
||||
* property {@link Field}
|
||||
*
|
||||
* @param word vyhledávaný výraz
|
||||
* @return list odpovídajících entit
|
||||
*/
|
||||
public List<?> globalSearch(String word);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package info.bukova.isspst.services;
|
||||
|
||||
import info.bukova.isspst.ModuleUtils;
|
||||
import info.bukova.isspst.dao.QueryDao;
|
||||
import info.bukova.isspst.data.BaseData;
|
||||
import info.bukova.isspst.data.User;
|
||||
@@ -24,6 +25,7 @@ import org.hibernate.search.query.dsl.QueryBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class FullTextServiceImpl implements FullTextService {
|
||||
@@ -55,7 +57,9 @@ public class FullTextServiceImpl implements FullTextService {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@PreAuthorize("hasPermission(this, 'PERM_SEARCH')")
|
||||
public List<?> search(Class<?> entityClass, String[] fields, String word) {
|
||||
checkActivity();
|
||||
FullTextSession session = Search.getFullTextSession(queryDao.getSession());
|
||||
QueryBuilder qb = session.getSearchFactory().buildQueryBuilder().forEntity(entityClass).get();
|
||||
|
||||
@@ -67,7 +71,9 @@ public class FullTextServiceImpl implements FullTextService {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@PreAuthorize("hasPermission(this, 'PERM_SEARCH')")
|
||||
public List<?> globalSearch(String word) {
|
||||
checkActivity();
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
|
||||
for (Class<?> clazz : classesForSearch()) {
|
||||
@@ -83,6 +89,12 @@ public class FullTextServiceImpl implements FullTextService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkActivity() {
|
||||
if (!ModuleUtils.getModule(this.getClass()).isActive()) {
|
||||
throw new ModuleNotActiveException();
|
||||
}
|
||||
}
|
||||
|
||||
private List<Class<?>> classesForSearch() {
|
||||
if (classesForSearch != null) {
|
||||
return classesForSearch;
|
||||
|
||||
@@ -2,7 +2,14 @@ package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.EntityUrlResolver;
|
||||
import info.bukova.isspst.data.BaseData;
|
||||
import info.bukova.isspst.data.DataModel;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Třída obecného transformačního objektu. Do výsledku nastaví property z rozhraní {@link DataModel}, které implementují všechny entity.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractResultTransformer implements ResultTransformer {
|
||||
|
||||
protected EntityUrlResolver urlResolver;
|
||||
@@ -27,6 +34,12 @@ public abstract class AbstractResultTransformer implements ResultTransformer {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Další transformace v závislosti na konkrétní třídě přdané entity
|
||||
*
|
||||
* @param object entita k transformaci
|
||||
* @param result výsledný transformovaný objekt
|
||||
*/
|
||||
protected abstract void transform(Object object, SearchResult result);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.StringUtils;
|
||||
import info.bukova.isspst.data.Order;
|
||||
|
||||
public class OrderResultTransformer extends AbstractResultTransformer implements ResultTransformer {
|
||||
@@ -7,8 +8,8 @@ public class OrderResultTransformer extends AbstractResultTransformer implements
|
||||
@Override
|
||||
protected void transform(Object object, SearchResult result) {
|
||||
Order order = (Order)object;
|
||||
result.setRecordName("Objednávka: " + order.getNumser());
|
||||
result.setDescription(order.getDescription() + ", dodavatel: " + order.getSuplier().getCompany());
|
||||
result.setRecordName(StringUtils.localize("Order") + ": " + order.getNumser());
|
||||
result.setDescription(order.getDescription() + ", " + StringUtils.localize("Supplier") + ": " + order.getSuplier().getCompany());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.Constants;
|
||||
import info.bukova.isspst.StringUtils;
|
||||
import info.bukova.isspst.data.Requirement;
|
||||
|
||||
public class RequirementResultTransformer extends AbstractResultTransformer implements ResultTransformer {
|
||||
@@ -7,7 +9,15 @@ public class RequirementResultTransformer extends AbstractResultTransformer impl
|
||||
@Override
|
||||
protected void transform(Object object, SearchResult result) {
|
||||
Requirement req = (Requirement)object;
|
||||
result.setRecordName("Požadavek na nákup/službu: " + req.getNumser());
|
||||
String moduleName;
|
||||
|
||||
if (req.getKind() != null && req.getKind().equals(Constants.REQ_TYPE_SERVICES)) {
|
||||
moduleName = StringUtils.localize("ServiceRequirement");
|
||||
} else {
|
||||
moduleName = StringUtils.localize("MaterialRequirement");
|
||||
}
|
||||
|
||||
result.setRecordName(moduleName + ": " + req.getNumser());
|
||||
result.setDescription(req.getDescription());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,29 @@ package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.EntityUrlResolver;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Rozhraní transformačního objektu výsledků fulltextového vyhledávání. Z vyhledaných entit potřebujeme na UI
|
||||
* objekty třídy {@link SearchResult}.
|
||||
*
|
||||
*/
|
||||
public interface ResultTransformer {
|
||||
|
||||
/**
|
||||
* Transformuje entitu na {@link SearchResult}
|
||||
*
|
||||
* @param object entita k transformaci
|
||||
* @return objekt {@link SearchResult}
|
||||
*/
|
||||
public SearchResult transformObject(Object object);
|
||||
|
||||
|
||||
/**
|
||||
* Nastaví objekt vyhodnocovače URL záznamu, aby bylo možné generovat URL pro přímý přístup do příslušné agendy a vystavení kurzoru v gridu.
|
||||
*
|
||||
* @param resolver vyhodnocovač URL
|
||||
*/
|
||||
public void setUrlResolver(EntityUrlResolver resolver);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.UrlResolverHolder;
|
||||
import info.bukova.isspst.services.FullTextService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.zkoss.bind.annotation.Command;
|
||||
import org.zkoss.bind.annotation.NotifyChange;
|
||||
import org.zkoss.zk.ui.select.annotation.WireVariable;
|
||||
|
||||
import info.bukova.isspst.UrlResolverHolder;
|
||||
import info.bukova.isspst.data.BaseData;
|
||||
import info.bukova.isspst.data.Requirement;
|
||||
import info.bukova.isspst.data.TripRequirement;
|
||||
import info.bukova.isspst.services.FullTextService;
|
||||
|
||||
public class SearchForm {
|
||||
|
||||
@WireVariable
|
||||
@@ -33,9 +30,7 @@ public class SearchForm {
|
||||
return;
|
||||
}
|
||||
|
||||
//String[] fields = {"items.textItem", "description"};
|
||||
List<?> result = fulltextService.globalSearch(keyWord);
|
||||
//List<?> result = fulltextService.search(Requirement.class, fields, keyWord);
|
||||
|
||||
SearchListTransformer srt = new SearchListTransformer(urlResolverHolder);
|
||||
results = srt.transform(result);
|
||||
|
||||
@@ -5,6 +5,12 @@ import info.bukova.isspst.UrlResolverHolder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Transformuje list různých entit na list objektů třídy {@link SearchResult}
|
||||
*
|
||||
*/
|
||||
public class SearchListTransformer {
|
||||
|
||||
private UrlResolverHolder urlResolverHolder;
|
||||
@@ -15,6 +21,9 @@ public class SearchListTransformer {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param urlResolverHolder kontajner vyhodnocovačů URL (objekt se konfiguruje přes Spring context)
|
||||
*/
|
||||
public SearchListTransformer(UrlResolverHolder urlResolverHolder) {
|
||||
super();
|
||||
this.urlResolverHolder = urlResolverHolder;
|
||||
|
||||
@@ -4,6 +4,12 @@ import info.bukova.isspst.data.User;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Třída výsledků fulltextového vyhledávání. Na property objektu této třídy jsou bindovány prvky ze zobrazovacího ZUL souboru.
|
||||
*
|
||||
*/
|
||||
public class SearchResult {
|
||||
|
||||
private String recordName;
|
||||
|
||||
@@ -5,8 +5,20 @@ import info.bukova.isspst.data.Requirement;
|
||||
import info.bukova.isspst.data.TripBill;
|
||||
import info.bukova.isspst.data.TripRequirement;
|
||||
|
||||
/**
|
||||
* @author Pepa Rokos
|
||||
*
|
||||
* Tovární třída transformačních objektů
|
||||
*
|
||||
*/
|
||||
public class TransformerFactory {
|
||||
|
||||
/**
|
||||
* Vrací transformační objekt pro předanou entitu
|
||||
*
|
||||
* @param object entita k transformaci
|
||||
* @return transformační objekt
|
||||
*/
|
||||
public static ResultTransformer transformerFor(Object object) {
|
||||
if (object instanceof TripBill) {
|
||||
return new TripBillTransformer();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.StringUtils;
|
||||
import info.bukova.isspst.data.TripBill;
|
||||
|
||||
public class TripBillTransformer extends AbstractResultTransformer implements ResultTransformer {
|
||||
@@ -7,8 +8,10 @@ public class TripBillTransformer extends AbstractResultTransformer implements Re
|
||||
@Override
|
||||
protected void transform(Object object, SearchResult result) {
|
||||
TripBill tb = (TripBill)object;
|
||||
result.setRecordName("Vyúčtování služební cesty: " + tb.getRequirement().getNumser());
|
||||
result.setDescription("Z " + tb.getRequirement().getFrom() + " do " + tb.getRequirement().getTo() + " - " + tb.getRequirement().getDescription());
|
||||
result.setRecordName(StringUtils.localize("TravelOrdersFormTitle") + ": " + tb.getRequirement().getNumser());
|
||||
result.setDescription(StringUtils.localize("TravelOrdersGridFrom") + " "
|
||||
+ tb.getRequirement().getFrom() + " " + StringUtils.localize("TravelOrdersGridTo") + " "
|
||||
+ tb.getRequirement().getTo() + " - " + tb.getRequirement().getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package info.bukova.isspst.ui.search;
|
||||
|
||||
import info.bukova.isspst.StringUtils;
|
||||
import info.bukova.isspst.data.TripRequirement;
|
||||
|
||||
public class TripRequirementTransformer extends AbstractResultTransformer implements ResultTransformer {
|
||||
@@ -7,8 +8,10 @@ public class TripRequirementTransformer extends AbstractResultTransformer implem
|
||||
@Override
|
||||
protected void transform(Object object, SearchResult result) {
|
||||
TripRequirement tr = (TripRequirement)object;
|
||||
result.setRecordName("Žádost o služební cestu: " + tr.getNumser());
|
||||
result.setDescription("Z " + tr.getFrom() + " do " + tr.getTo() + " - " + tr.getDescription());
|
||||
result.setRecordName(StringUtils.localize("TripRequirement") + ": " + tr.getNumser());
|
||||
result.setDescription(StringUtils.localize("TravelOrdersGridFrom") + " "
|
||||
+ tr.getFrom() + " " + StringUtils.localize("TravelOrdersGridTo") + " "
|
||||
+ tr.getTo() + " - " + tr.getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user