Author: glandais Date: 2008-02-22 19:43:28 +0000 (Fri, 22 Feb 2008) New Revision: 1204 Added: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetFilter.java trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetHitCollector.java Modified: trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManager.java trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManagerImpl.java trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermission.java trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermissionImpl.java trunk/simexplorer-is/simexplorer-is-service/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineSecuImpl.java trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/factories/BaseEntityFactory.java trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineImpl.java trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/grid/ElementDataSource.java trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/pages/ElementList.java Log: Efficient security filtering of lists Modified: trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManager.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManager.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManager.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -17,6 +17,7 @@ * ##% */ package fr.cemagref.simexplorer.is.security.credentials; +import java.util.Collection; import java.util.List; import javax.ejb.Local; @@ -73,5 +74,32 @@ * @return the permissions owned by */ public List<Permission> getPermissionsOwnedBy(User user); + + /** + * Gets the businnes ids of elements visible by user. null means all elements. + * + * @param token the token + * + * @return the elements visible by + */ + public Collection<String> getElementsVisibleBy(String token); + /** + * Gets the user filter. + * + * @param token the token + * + * @return the user filter + */ + public String getUserFilter(String token); + + /** + * Checks if is cache invalid for. + * + * @param userFilter the user filter + * + * @return true, if is cache invalid for + */ + public boolean isCacheValidFor(String userFilter); + } Modified: trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManagerImpl.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManagerImpl.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/credentials/CredentialManagerImpl.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -17,7 +17,11 @@ * ##% */ package fr.cemagref.simexplorer.is.security.credentials; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.ejb.EJB; import javax.ejb.Local; @@ -48,6 +52,12 @@ @EJB private DaoPermission daoPermission; + /** The Constant elementsVisibleByCache. */ + private static final List<String> usersCached = new ArrayList<String>(); + + /** The Constant elementsVisibleSynchronizer. */ + private final static Object usersCachedSynchronizer = new Object(); + /** * Gets the relative level. * @@ -148,6 +158,9 @@ p.setOwner(true); daoPermission.updatePermission(p); } + synchronized (usersCachedSynchronizer) { + usersCached.clear(); + } } /* (non-Javadoc) @@ -165,6 +178,9 @@ @Override public void setPermissions(String uuid, Permission[] permissions) { daoPermission.setPermissions(uuid, permissions); + synchronized (usersCachedSynchronizer) { + usersCached.clear(); + } } /* (non-Javadoc) @@ -176,4 +192,63 @@ return permissionsOwnedBy; } + /* (non-Javadoc) + * @see fr.cemagref.simexplorer.is.security.credentials.CredentialManager#getElementsVisibleBy(fr.cemagref.simexplorer.is.security.entities.User) + */ + @Override + public Collection<String> getElementsVisibleBy(String token) { + String userFilter = getUserFilter(token); + + List<String> businessIdsVisibleBy = null; + + User user = daoActor.getLoggedUser(token); + if (!user.isSuperAdmin()) { + Set<Actor> actors = new HashSet<Actor>(); + getActors(user, actors); + businessIdsVisibleBy = daoPermission.getBusinessIdsVisibleBy(actors); + } + + synchronized (usersCachedSynchronizer) { + usersCached.add(userFilter); + } + + return businessIdsVisibleBy; + } + + /** + * Gets the actors. + * + * @param actor the actor + * @param actors the actors + */ + private void getActors(Actor actor, Collection<Actor> actors) { + actors.add(actor); + List<Group> groups = actor.getGroups(); + for (Group group : groups) { + getActors(group, actors); + } + actors.addAll(groups); + } + + /* (non-Javadoc) + * @see fr.cemagref.simexplorer.is.security.credentials.CredentialManager#getUserFilter(java.lang.String) + */ + @Override + public String getUserFilter(String token) { + User user = daoActor.getLoggedUser(token); + return user.getId().toString(); + } + + /* (non-Javadoc) + * @see fr.cemagref.simexplorer.is.security.credentials.CredentialManager#isCacheInvalidFor(java.lang.String) + */ + @Override + public boolean isCacheValidFor(String userFilter) { + boolean result; + synchronized (usersCachedSynchronizer) { + result = usersCached.contains(userFilter); + } + return result; + } + } Modified: trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermission.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermission.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermission.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -17,11 +17,15 @@ * ##% */ package fr.cemagref.simexplorer.is.security.dao; +import java.util.Collection; import java.util.List; import fr.cemagref.simexplorer.is.security.entities.Actor; import fr.cemagref.simexplorer.is.security.entities.Permission; +/** + * The Interface DaoPermission. + */ public interface DaoPermission { /** @@ -73,5 +77,14 @@ * @param permissions the permissions */ public void setPermissions(String uuid, Permission[] permissions); + + /** + * Gets the business ids visible by. + * + * @param actors the actors + * + * @return ids visible + */ + public List<String> getBusinessIdsVisibleBy(Collection<Actor> actors); } Modified: trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermissionImpl.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermissionImpl.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-security/src/java/fr/cemagref/simexplorer/is/security/dao/DaoPermissionImpl.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -17,6 +17,7 @@ * ##% */ package fr.cemagref.simexplorer.is.security.dao; +import java.util.Collection; import java.util.List; import javax.ejb.Stateless; @@ -98,4 +99,15 @@ public void updatePermission(Permission p) { em.merge(p); } + + @Override + public List<String> getBusinessIdsVisibleBy(Collection<Actor> actors) { + StringBuffer query = new StringBuffer(); + query.append("select p.businessId from Permission p").append( + " where (p.canRead = true or p.canAdmin = true or p.owner = true)").append( + " and p.actor in (:actors)"); + List<String> businessIds = CollectionUtil.toGenericList(em.createQuery(query.toString()).setParameter("actors", + actors).getResultList(), String.class); + return businessIds; + } } Modified: trunk/simexplorer-is/simexplorer-is-service/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineSecuImpl.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-service/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineSecuImpl.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-service/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineSecuImpl.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -18,6 +18,7 @@ package fr.cemagref.simexplorer.is.storage.engine; import java.io.InputStream; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -30,6 +31,7 @@ import fr.cemagref.simexplorer.is.entities.metadata.Version; import fr.cemagref.simexplorer.is.exceptions.SimExplorerException; import fr.cemagref.simexplorer.is.exceptions.SimExplorerSecurityException; +import fr.cemagref.simexplorer.is.exceptions.SimExplorerTechnicalException; import fr.cemagref.simexplorer.is.security.credentials.CredentialManager; import fr.cemagref.simexplorer.is.security.entities.Permission; import fr.cemagref.simexplorer.is.storage.SortColumn; @@ -45,7 +47,7 @@ /** The credential manager. */ @EJB private CredentialManager credentialManager; - + /* (non-Javadoc) * @see fr.cemagref.simexplorer.is.storage.engine.StorageEngineImpl#deleteElement(java.lang.String, java.lang.String, fr.cemagref.simexplorer.is.entities.metadata.Version) */ @@ -80,10 +82,10 @@ @Override public MetaData[] findElementsByType(String token, String type, boolean onlyLatest, int start, int count, SortColumn column, SortOrder sortOrder) throws SimExplorerException { - MetaData[] list; - list = super.findElementsByType(token, type, onlyLatest, start, count, column, sortOrder); - // TODO how to filter without losing pagination? - return list; + String userFilter = getUserFilter(token); + List<MetaData> elements = database.findElementsByType(type, onlyLatest, start, count, column, sortOrder, + userFilter); + return convertList(elements); } /* (non-Javadoc) @@ -91,8 +93,8 @@ */ @Override public int findElementsByTypeCount(String token, String type, boolean onlyLatest) throws SimExplorerException { - // TODO how to filter without losing pagination? - return super.findElementsByTypeCount(token, type, onlyLatest); + String userFilter = getUserFilter(token); + return database.findElementsByTypeCount(type, onlyLatest, userFilter); } /* (non-Javadoc) @@ -101,8 +103,10 @@ @Override public MetaData[] findFullText(String token, String query, boolean onlyLatest, int indexStart, int count, SortColumn column, SortOrder sortOrder) throws SimExplorerException { - // TODO how to filter without losing pagination? - return super.findFullText(token, query, onlyLatest, indexStart, count, column, sortOrder); + String userFilter = getUserFilter(token); + List<MetaData> elements = database.findElementsByContentSearch(query, onlyLatest, indexStart, count, column, + sortOrder, userFilter); + return convertList(elements); } /* (non-Javadoc) @@ -110,10 +114,27 @@ */ @Override public int findFullTextCount(String token, String query, boolean onlyLatest) throws SimExplorerException { - // TODO how to filter without losing pagination? - return super.findFullTextCount(token, query, onlyLatest); + String userFilter = getUserFilter(token); + return database.findElementsByContentSearchCount(query, onlyLatest, userFilter); } + /** + * Gets the user filter. + * + * @param token the token + * + * @return the user filter + * + * @throws SimExplorerTechnicalException the sim explorer technical exception + */ + private String getUserFilter(String token) throws SimExplorerTechnicalException { + String userFilter = credentialManager.getUserFilter(token); + if (!credentialManager.isCacheValidFor(userFilter)) { + database.updateFilter(userFilter, credentialManager.getElementsVisibleBy(token)); + } + return userFilter; + } + /* (non-Javadoc) * @see fr.cemagref.simexplorer.is.storage.engine.StorageEngineImpl#getMetadata(java.lang.String, java.lang.String, fr.cemagref.simexplorer.is.entities.metadata.Version) */ Modified: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/factories/BaseEntityFactory.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/factories/BaseEntityFactory.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/factories/BaseEntityFactory.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -28,366 +28,10 @@ */ public abstract class BaseEntityFactory<E extends BaseEntity> { - private static XStream xstream = new XStream(); + private static XStream xstream = new XStream(); public static XStream getXstream() { return xstream; } - -// /** The document builder. */ -// private static DocumentBuilder documentBuilder = null; -// -// /** The factories. */ -// private static Map<String, BaseEntityFactory<? extends DataEntity>> factories = new HashMap<String, BaseEntityFactory<? extends DataEntity>>(); -// -// /* -// * Static methods - Retrieve factories, get XML document builder -// */ -// -// /** -// * Retrieve instance of the factory. -// * -// * @param <E> Entity type -// * -// * @param entityClass Class wanted -// * -// * @return Factory -// * -// * @throws SimExplorerException the exception -// */ -// @SuppressWarnings("unchecked") -// public static <E extends DataEntity> BaseEntityFactory<E> getFactory(Class entityClass) throws SimExplorerException { -// BaseEntityFactory<E> result = (BaseEntityFactory<E>) factories.get(entityClass.getSimpleName()); -// if (result == null) { -// String elementFactoryClassName = BaseEntityFactory.class.getPackage().getName() + "." -// + entityClass.getSimpleName() + FACTORY_SUFFIX; -// -// Class<? extends BaseEntityFactory<E>> factoryClass; -// try { -// factoryClass = (Class<? extends BaseEntityFactory<E>>) Class.forName(elementFactoryClassName) -// .asSubclass(BaseEntityFactory.class); -// result = factoryClass.newInstance(); -// } catch (Exception e) { -// throw new SimExplorerTechnicalException(e); -// } -// -// factories.put(entityClass.getSimpleName(), result); -// } -// return result; -// } -// -// /** -// * Retrieve a factory with class name. -// * -// * @param entityClassName the entity class name -// * -// * @return the factory -// * -// * @throws SimExplorerException the exception -// */ -// public static BaseEntityFactory<? extends DataEntity> getFactory(String entityClassName) -// throws SimExplorerException { -// Class<? extends DataEntity> entityClass; -// try { -// entityClass = Class.forName(entityClassName).asSubclass(DataEntity.class); -// } catch (ClassNotFoundException e) { -// throw new SimExplorerTechnicalException(e); -// } -// return getFactory(entityClass); -// } -// -// /** -// * Retrieve an instance of document builder. -// * -// * @return XML document builder -// * @throws ParserConfigurationException -// * -// */ -// public static synchronized DocumentBuilder getXMLBuilder() throws ParserConfigurationException { -// if (documentBuilder == null) { -// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); -// documentBuilder = factory.newDocumentBuilder(); -// return documentBuilder; -// } -// return documentBuilder; -// } -// -// /* -// * Entity methods - Instanciate, load and save to XML/streams -// */ -// -// /** -// * Instanciate an element. -// * -// * @return Element -// */ -// public abstract E createInstance(); -// -// /** -// * Load an element from an XML node. -// * -// * @param xmlElement the xml element -// * -// * @return the E -// * -// * @throws SimExplorerException the exception -// */ -// public E loadElement(Element xmlElement) throws SimExplorerException { -// E element = createInstance(); -// return element; -// } -// -// /** -// * Load an element from a XML stream. -// * -// * @param stream the stream -// * -// * @return the E -// * -// * @throws SimExplorerException the exception -// */ -// public E loadElement(InputStream stream) throws SimExplorerException { -// Element rootElement; -// try { -// Document document = getXMLBuilder().parse(stream); -// rootElement = (Element) document.getFirstChild(); -// } catch (Exception e) { -// throw new SimExplorerTechnicalException(e); -// } -// E element = loadElement(rootElement); -// return element; -// } -// -// /** -// * Save an element to a XML node. -// * -// * @param document XML document -// * @param xmlElement XML node storing the element (not null) -// * @param element Element to save -// * -// * @throws SimExplorerException the exception -// */ -// public abstract void saveElement(Document document, Element xmlElement, E element) throws SimExplorerException; -// -// /** -// * Save an element to a XML stream. -// * -// * @param rootNodeName the root node name -// * @param element the element -// * -// * @return the input stream -// * -// * @throws SimExplorerException the exception -// */ -// public InputStream saveElement(String rootNodeName, E element) throws SimExplorerException { -// Document xmlDocument; -// Element rootNode; -// try { -// xmlDocument = getXMLBuilder().newDocument(); -// // DOM properties -// xmlDocument.setXmlVersion("1.0"); -// xmlDocument.setXmlStandalone(true); -// // DOM tree -// rootNode = xmlDocument.createElement(rootNodeName); -// } catch (Exception e) { -// throw new SimExplorerTechnicalException(e); -// } -// saveElement(xmlDocument, rootNode, element); -// try { -// xmlDocument.appendChild(rootNode); -// DOMSource domSource = new DOMSource(xmlDocument); -// -// PipedOutputStream os = new PipedOutputStream(); -// PipedInputStream is = new PipedInputStream(os); -// -// XMLStreamEncoder xse = new XMLStreamEncoder(domSource, os); -// xse.start(); -// -// return is; -// } catch (Exception e) { -// throw new SimExplorerTechnicalException(e); -// } -// } -// -// /* -// * Collection methods : Help load/save of inner collections -// */ -// -// /** -// * Load a collection inside a node. -// * -// * @param <T> Entity type -// * -// * @param tagSetName Tag of the node of the collection -// * @param tagName Tag of the node containing an item -// * @param clazz Class type -// * @param xmlElement Node containing the collection -// * @param parentData Element holding the collection -// * -// * @return the set< t> -// * -// * @throws SimExplorerException the exception -// */ -// public <T extends DataEntity> List<T> loadCollection(String tagSetName, String tagName, Class<T> clazz, -// Element xmlElement, DataEntity parentData) throws SimExplorerException { -// List<T> entities = new ArrayList<T>(); -// -// // Retrieve XML node containing the collection -// Element xmlCollection = getXMLElementByTagName(xmlElement, tagSetName); -// if (xmlCollection != null) { -// // Retrieve element factory -// BaseEntityFactory<T> elementFactory = getFactory(clazz); -// -// // Retrieve all XML elements -// List<Element> list = getXMLElementsByTagName(xmlCollection, tagName); -// for (Element element : list) { -// // Convert the XML node to entity -// T entity = elementFactory.loadElement(element); -// entity.setParentData(parentData); -// entities.add(entity); -// } -// } -// -// return entities; -// } -// -// /** -// * Save a collection of elements to XML node. -// * -// * @param <T> Entity type -// * -// * @param entities the entities -// * @param tagSetName the tag set name -// * @param tagName the tag name -// * @param clazz the clazz -// * @param document the document -// * @param xmlElement the xml element -// * -// * @throws SimExplorerException the exception -// */ -// public <T extends DataEntity> void saveCollection(List<T> entities, String tagSetName, String tagName, -// Class<T> clazz, Document document, Element xmlElement) throws SimExplorerException { -// if (entities != null && entities.size() > 0) { -// Element xmlCollection = document.createElement(tagSetName); -// BaseEntityFactory<T> elementFactory = getFactory(clazz); -// for (T entity : entities) { -// Element childElement = document.createElement(tagName); -// elementFactory.saveElement(document, childElement, entity); -// xmlCollection.appendChild(childElement); -// } -// xmlElement.appendChild(xmlCollection); -// } -// } -// -// /** -// * Save an element as a XML stream. -// * -// * @param node the node -// * -// * @return the input stream -// * -// * @throws SimExplorerException the exception -// */ -// public static InputStream serializeElement(Node node) throws SimExplorerException { -// try { -// Document xmlDocument = getXMLBuilder().newDocument(); -// // DOM properties -// xmlDocument.setXmlVersion("1.0"); -// xmlDocument.setXmlStandalone(true); -// // DOM tree -// xmlDocument.appendChild(xmlDocument.importNode(node, true)); -// DOMSource domSource = new DOMSource(xmlDocument); -// -// PipedOutputStream os = new PipedOutputStream(); -// PipedInputStream is = new PipedInputStream(os); -// -// XMLStreamEncoder xse = new XMLStreamEncoder(domSource, os); -// xse.start(); -// -// return is; -// } catch (Exception e) { -// throw new SimExplorerTechnicalException(e); -// } -// } -// -// /* -// * XML methods : set, get properties -// */ -// -// /** -// * Set a property in XML. -// * -// * @param document XML document -// * @param xmlElement Node to modify -// * @param tagName Tag of created node -// * @param value Value of node -// */ -// protected void setXMLProperty(Document document, Element xmlElement, String tagName, Object value) { -// if (value != null) { -// Element xmlProperty = document.createElement(tagName); -// Text xmlDescriptionText = document.createTextNode(value.toString()); -// xmlProperty.appendChild(xmlDescriptionText); -// xmlElement.appendChild(xmlProperty); -// } -// } -// -// /** -// * Get a property in XML. -// * -// * @param xmlElement Source node -// * @param tagName Tag name of property -// * -// * @return Property value -// */ -// public String getXMLProperty(Element xmlElement, String tagName) { -// Element element = getXMLElementByTagName(xmlElement, tagName); -// if (element != null) { -// return element.getFirstChild().getNodeValue(); -// } -// return null; -// } -// -// /* -// * XML methods : retrieve nodes -// */ -// -// /** -// * Retrieve XML element just under with specified tag name. -// * -// * @param xmlElement the xml element -// * @param tagName the tag name -// * -// * @return First child element with tagName -// */ -// public Element getXMLElementByTagName(Element xmlElement, String tagName) { -// List<Element> elements = getXMLElementsByTagName(xmlElement, tagName); -// if (elements.size() > 0) { -// return elements.iterator().next(); -// } -// return null; -// } -// -// /** -// * Retrieve all XML elements just under with specified tag name. -// * -// * @param xmlElement the xml element -// * @param tagName the tag name -// * -// * @return Children with tagName -// */ -// public List<Element> getXMLElementsByTagName(Element xmlElement, String tagName) { -// List<Element> elements = new ArrayList<Element>(); -// -// NodeList nodes = xmlElement.getChildNodes(); -// for (int i = 0; i < nodes.getLength(); i++) { -// Node node = nodes.item(i); -// if (node instanceof Element && tagName.equals(((Element) node).getTagName())) { -// elements.add((Element) node); -// } -// } -// return elements; -// } - - } Modified: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -18,6 +18,7 @@ package fr.cemagref.simexplorer.is.storage.database; import java.io.Reader; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -25,6 +26,7 @@ import fr.cemagref.simexplorer.is.entities.metadata.MetaData; import fr.cemagref.simexplorer.is.entities.metadata.Version; import fr.cemagref.simexplorer.is.exceptions.SimExplorerException; +import fr.cemagref.simexplorer.is.exceptions.SimExplorerTechnicalException; import fr.cemagref.simexplorer.is.storage.SortColumn; import fr.cemagref.simexplorer.is.storage.SortOrder; @@ -165,20 +167,6 @@ * Empty list if no element. * * @param properties Matching properties needed - * - * @return Element list - * - * @throws SimExplorerException the sim explorer storage exception - */ - public List<MetaData> findElementsByProperties(Map<String, String> properties) throws SimExplorerException { - return findElementsByProperties(properties, 0, -1, SortColumn.None, SortOrder.Ascending); - } - - /** - * Retrieve elements with specific properties<br> - * Empty list if no element. - * - * @param properties Matching properties needed * @param start Index of first element returned * @param count Number of elements to return * @param sortOrder the order @@ -189,7 +177,7 @@ * @throws SimExplorerException the sim explorer storage exception */ public abstract List<MetaData> findElementsByProperties(Map<String, String> properties, int start, int count, - SortColumn column, SortOrder sortOrder) throws SimExplorerException; + SortColumn column, SortOrder sortOrder, String userFilter) throws SimExplorerException; /** * Retrieve element count specific properties. @@ -200,7 +188,8 @@ * * @throws SimExplorerException the sim explorer storage exception */ - public abstract int findElementsByPropertiesCount(Map<String, String> properties) throws SimExplorerException; + public abstract int findElementsByPropertiesCount(Map<String, String> properties, String userFilter) + throws SimExplorerException; /** * Prepare properties for query. @@ -235,21 +224,56 @@ */ public List<MetaData> findElementsByType(String type, boolean onlyLatest, int start, int count, SortColumn column, SortOrder sortOrder) throws SimExplorerException { - return findElementsByProperties(getPropertiesByType(type, onlyLatest), start, count, column, sortOrder); + return findElementsByType(type, onlyLatest, start, count, column, sortOrder, null); } /** + * Find elements by type. + * + * @param type the type + * @param onlyLatest the only latest + * @param start the start + * @param count the count + * @param column the column + * @param sortOrder the sort order + * @param elementsVisible the elements visible + * + * @return the list< meta data> + * + * @throws SimExplorerException the sim explorer exception + */ + public List<MetaData> findElementsByType(String type, boolean onlyLatest, int start, int count, SortColumn column, + SortOrder sortOrder, String user) throws SimExplorerException { + return findElementsByProperties(getPropertiesByType(type, onlyLatest), start, count, column, sortOrder, user); + } + + /** * Number of elements of the type. * * @param type Type wanted * @param onlyLatest Only latest elements + * @param userFilter the user filter * * @return Number of elements * * @throws SimExplorerException the sim explorer storage exception */ + public int findElementsByTypeCount(String type, boolean onlyLatest, String userFilter) throws SimExplorerException { + return findElementsByPropertiesCount(getPropertiesByType(type, onlyLatest), userFilter); + } + + /** + * Find elements by type count. + * + * @param type the type + * @param onlyLatest the only latest + * + * @return the int + * + * @throws SimExplorerException the sim explorer exception + */ public int findElementsByTypeCount(String type, boolean onlyLatest) throws SimExplorerException { - return findElementsByPropertiesCount(getPropertiesByType(type, onlyLatest)); + return findElementsByPropertiesCount(getPropertiesByType(type, onlyLatest), null); } /** @@ -268,9 +292,28 @@ * @throws SimExplorerException the sim explorer storage exception */ public abstract List<MetaData> findElementsByContentSearch(String queryText, boolean onlyLatest, int start, - int count, SortColumn column, SortOrder sortOrder) throws SimExplorerException; + int count, SortColumn column, SortOrder sortOrder, String userFilter) throws SimExplorerException; /** + * Find elements by content search. + * + * @param queryText the query text + * @param onlyLatest the only latest + * @param start the start + * @param count the count + * @param column the column + * @param sortOrder the sort order + * + * @return the list< meta data> + * + * @throws SimExplorerException the sim explorer exception + */ + public List<MetaData> findElementsByContentSearch(String queryText, boolean onlyLatest, int start, int count, + SortColumn column, SortOrder sortOrder) throws SimExplorerException { + return findElementsByContentSearch(queryText, onlyLatest, start, count, column, sortOrder, null); + } + + /** * Retrieve element count with specific content. * * @param queryText Searched text @@ -280,9 +323,32 @@ * * @throws SimExplorerException the sim explorer storage exception */ - public abstract int findElementsByContentSearchCount(String queryText, boolean onlyLatest) + public abstract int findElementsByContentSearchCount(String queryText, boolean onlyLatest, String userFilter) throws SimExplorerException; + /** + * Find elements by content search count. + * + * @param queryText the query text + * @param onlyLatest the only latest + * + * @return the int + * + * @throws SimExplorerException the sim explorer exception + */ + public int findElementsByContentSearchCount(String queryText, boolean onlyLatest) throws SimExplorerException { + return findElementsByContentSearchCount(queryText, onlyLatest, null); + } + + /** + * Update filter. + * + * @param userFilter the user filter + * @param visibleItems the visible items + * @throws SimExplorerTechnicalException + */ + public abstract void updateFilter(String userFilter, Collection<String> visibleItems) throws SimExplorerTechnicalException; + // Delete /** Added: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetFilter.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetFilter.java (rev 0) +++ trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetFilter.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -0,0 +1,52 @@ +/* +* ##% Copyright (C) 2008 Code Lutin, Gabriel Landais +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* ##% */ +package fr.cemagref.simexplorer.is.storage.database.lucene; + +import java.io.IOException; +import java.util.BitSet; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.Filter; + +/** + * The Class BitSetFilter. + */ +public class BitSetFilter extends Filter { + + /** The bit set. */ + private BitSet bitSet; + + /* (non-Javadoc) + * @see org.apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader) + */ + @Override + public BitSet bits(IndexReader reader) throws IOException { + return bitSet; + } + + /** + * Instantiates a new bit set filter. + * + * @param bitSet the bit set + */ + public BitSetFilter(BitSet bitSet) { + super(); + this.bitSet = bitSet; + } + +} Added: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetHitCollector.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetHitCollector.java (rev 0) +++ trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/BitSetHitCollector.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -0,0 +1,49 @@ +/* +* ##% Copyright (C) 2008 Code Lutin, Gabriel Landais +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* ##% */ +package fr.cemagref.simexplorer.is.storage.database.lucene; + +import java.util.BitSet; + +import org.apache.lucene.search.HitCollector; + +/** + * The Class BitSetHitCollector. + */ +public class BitSetHitCollector extends HitCollector { + + /** The bits. */ + private BitSet bits = new BitSet(); + + /* (non-Javadoc) + * @see org.apache.lucene.search.HitCollector#collect(int, float) + */ + @Override + public void collect(int doc, float score) { + bits.set(doc); + } + + /** + * Gets the bits. + * + * @return the bits + */ + public BitSet getBits() { + return bits; + } + +} Modified: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -21,6 +21,8 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.BitSet; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -41,6 +43,8 @@ import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.HitCollector; import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; @@ -72,6 +76,9 @@ /** The Constant log. */ private static final Log log = LogFactory.getLog(LuceneDatabase.class); + /** The Constant filters. */ + private static final Map<String, Filter> filters = new HashMap<String, Filter>(); + /** DB folder. */ private String dbFolder; @@ -102,6 +109,12 @@ /** The Constant writerSynchronizer. */ private final static Object writerSynchronizer = new Object(); + /** The Constant writerSynchronizer. */ + private final static Object filterSynchronizer = new Object(); + + /** + * Instantiates a new lucene database. + */ public LuceneDatabase() { Properties config = Config.getProperties(); this.dbFolder = String.valueOf(config.getProperty(Config.DB_FOLDER_PROPERTY)); @@ -109,6 +122,9 @@ log.info(this); } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ @Override public String toString() { return super.toString() + "<dbFolder:" + dbFolder + ", optimizePeriod:" + optimizePeriod + ">"; @@ -175,6 +191,130 @@ } } + /** + * Filter search. + * + * @param searcher the searcher + * @param query the query + * @param userFilter the user filter + * + * @return the hits + * + * @throws IOException Signals that an I/O exception has occurred. + */ + private Hits filterSearch(Searcher searcher, Query query, String userFilter) throws IOException { + return filterSearch(searcher, query, userFilter, null); + } + + /** + * Filter search. + * + * @param searcher the searcher + * @param query the query + * @param userFilter the user filter + * @param sorting the sorting + * + * @return the hits + * + * @throws IOException Signals that an I/O exception has occurred. + */ + private Hits filterSearch(Searcher searcher, Query query, String userFilter, Sort sorting) throws IOException { + Hits result = null; + Filter filter = null; + if (userFilter != null) { + synchronized (filterSynchronizer) { + filter = filters.get(userFilter); + } + } + + if (filter == null) { + if (sorting == null) { + result = searcher.search(query); + } else { + result = searcher.search(query, sorting); + } + } else { + synchronized (filter) { + if (sorting == null) { + result = searcher.search(query, filter); + } else { + result = searcher.search(query, filter, sorting); + } + } + } + return result; + } + + /** + * Creates the bit set. + * + * @param visibleItems the visible items + * + * @return the bit set + * + * @throws SimExplorerTechnicalException the sim explorer technical exception + */ + private BitSet createBitSet(Collection<String> visibleItems) throws SimExplorerTechnicalException { + BooleanQuery query = new BooleanQuery(); + for (String string : visibleItems) { + query.add(new TermQuery(new Term(KEY_UUID, string)), BooleanClause.Occur.SHOULD); + } + + BitSetHitCollector bitSetHitCollector = new BitSetHitCollector(); + try { + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + searcher.search(query, bitSetHitCollector); + } finally { + // Release searcher instance + releaseSearcher(searcher); + } + } catch (Exception e) { + throw new SimExplorerTechnicalException(e); + } + + return bitSetHitCollector.getBits(); + } + + /** + * Creates the filter. + * + * @param visibleItems the visible items + * + * @return the filter + * + * @throws SimExplorerTechnicalException the sim explorer technical exception + */ + private Filter createFilter(Collection<String> visibleItems) throws SimExplorerTechnicalException { + List<BitSet> bitSets = new ArrayList<BitSet>(); + + int maxTerms = BooleanQuery.getMaxClauseCount(); + int i = 0; + + Collection<String> currentList = new ArrayList<String>(); + for (String uuid : visibleItems) { + currentList.add(uuid); + if (i == maxTerms) { + bitSets.add(createBitSet(currentList)); + currentList.clear(); + i = 0; + } else { + i++; + } + } + if (visibleItems.size() > 0 && i != 0) { + bitSets.add(createBitSet(currentList)); + } + + BitSet finalBitSet = new BitSet(); + for (BitSet bitSet : bitSets) { + finalBitSet.or(bitSet); + } + Filter result = new BitSetFilter(finalBitSet); + return result; + } + /* (non-Javadoc) * @see fr.cemagref.simexplorer.is.storage.database.Database#open(boolean) */ @@ -350,7 +490,7 @@ // Search elements Hits hits; - hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending); + hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending, null); return hits; } @@ -369,7 +509,7 @@ // Get current searcher instance Searcher searcher = getSearcher(); try { - Hits hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending); + Hits hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending, null); // Add all versions to a list versions = new ArrayList<Version>(); @@ -408,7 +548,7 @@ // Get current searcher instance Searcher searcher = getSearcher(); try { - Hits hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending); + Hits hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending, null); result = convertHitsToElements(hits, 0, -1); } finally { // Release searcher instance @@ -428,14 +568,15 @@ * @see fr.cemagref.simexplorer.is.storage.database.Database#findElementsByPropertiesCount(java.util.Map) */ @Override - public int findElementsByPropertiesCount(Map<String, String> properties) throws SimExplorerException { + public int findElementsByPropertiesCount(Map<String, String> properties, String userFilter) + throws SimExplorerException { int result = 0; try { // Get current searcher instance Searcher searcher = getSearcher(); try { - Hits hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending); + Hits hits = findHits(properties, searcher, SortColumn.None, SortOrder.Ascending, userFilter); result = hits.length(); } finally { // Release searcher instance @@ -454,14 +595,14 @@ */ @Override public List<MetaData> findElementsByProperties(Map<String, String> properties, int start, int count, - SortColumn column, SortOrder sortOrder) throws SimExplorerException { + SortColumn column, SortOrder sortOrder, String userFilter) throws SimExplorerException { List<MetaData> result = null; try { // Get current searcher instance Searcher searcher = getSearcher(); try { - Hits hits = findHits(properties, searcher, column, sortOrder); + Hits hits = findHits(properties, searcher, column, sortOrder, userFilter); result = convertHitsToElements(hits, start, count); } finally { // Release searcher instance @@ -481,7 +622,8 @@ * @see fr.cemagref.simexplorer.is.storage.database.Database#findElementsByContentSearchCount(java.lang.String, boolean) */ @Override - public int findElementsByContentSearchCount(String queryText, boolean onlyLatest) throws SimExplorerException { + public int findElementsByContentSearchCount(String queryText, boolean onlyLatest, String userFilter) + throws SimExplorerException { Query query; try { query = getQueryByContentSearch(queryText, onlyLatest); @@ -496,7 +638,7 @@ // Get current searcher instance Searcher searcher = getSearcher(); try { - hits = searcher.search(query); + hits = filterSearch(searcher, query, userFilter); // Return hits length result = hits.length(); } finally { @@ -510,39 +652,12 @@ return result; } - /** - * Retrieve a Lucene Sort for date sorting. - * - * @param column the column - * @param sortOrder the sort order - * - * @return null if no sort - */ - private Sort getSortDate(SortColumn column, SortOrder sortOrder) { - Sort sort; - if (column != SortColumn.None) { - SortField[] fields = new SortField[3]; - fields[1] = SortField.FIELD_SCORE; - fields[2] = SortField.FIELD_DOC; - - if (sortOrder == SortOrder.Ascending) { - fields[0] = new SortField(column.getColumn(), column.getType(), true); - } else { - fields[0] = new SortField(column.getColumn(), column.getType(), false); - } - sort = new Sort(fields); - } else { - sort = Sort.INDEXORDER; - } - return sort; - } - /* (non-Javadoc) * @see fr.cemagref.simexplorer.is.storage.database.Database#findElementsByContentSearch(java.lang.String, boolean, int, int, int) */ @Override public List<MetaData> findElementsByContentSearch(String queryText, boolean onlyLatest, int start, int count, - SortColumn column, SortOrder sortOrder) throws SimExplorerException { + SortColumn column, SortOrder sortOrder, String userFilter) throws SimExplorerException { Query query; try { query = getQueryByContentSearch(queryText, onlyLatest); @@ -557,7 +672,7 @@ // Get current searcher instance Searcher searcher = getSearcher(); try { - hits = searcher.search(query, getSortDate(column, sortOrder)); + hits = filterSearch(searcher, query, userFilter, getSortDate(column, sortOrder)); // Convert hits to elements result = convertHitsToElements(hits, start, count); } finally { @@ -574,6 +689,33 @@ } /** + * Retrieve a Lucene Sort for date sorting. + * + * @param column the column + * @param sortOrder the sort order + * + * @return null if no sort + */ + private Sort getSortDate(SortColumn column, SortOrder sortOrder) { + Sort sort; + if (column != SortColumn.None) { + SortField[] fields = new SortField[3]; + fields[1] = SortField.FIELD_SCORE; + fields[2] = SortField.FIELD_DOC; + + if (sortOrder == SortOrder.Ascending) { + fields[0] = new SortField(column.getColumn(), column.getType(), true); + } else { + fields[0] = new SortField(column.getColumn(), column.getType(), false); + } + sort = new Sort(fields); + } else { + sort = Sort.INDEXORDER; + } + return sort; + } + + /** * Retrieve a Lucene Query for a full text search. * * @param queryText String to match @@ -631,13 +773,14 @@ * @param searcher the searcher * @param column the column * @param sortOrder the sort order + * @param userFilter the user filter * * @return Documents and search handle * * @throws IOException Signals that an I/O exception has occurred. */ - private Hits findHits(Map<String, String> properties, Searcher searcher, SortColumn column, SortOrder sortOrder) - throws IOException { + private Hits findHits(Map<String, String> properties, Searcher searcher, SortColumn column, SortOrder sortOrder, + String userFilter) throws IOException { // Create a query with all parameters BooleanQuery query = new BooleanQuery(); for (Entry<String, String> kv : properties.entrySet()) { @@ -645,7 +788,7 @@ } Hits hits; - hits = searcher.search(query, getSortDate(column, sortOrder)); + hits = filterSearch(searcher, query, userFilter, getSortDate(column, sortOrder)); return hits; } @@ -820,6 +963,7 @@ * @param toField the to field * * @return the associated elements + * * @throws SimExplorerException if any pb */ protected List<MetaData> getAssociatedElements(MetaData mde, String fromField, String toField) @@ -908,4 +1052,17 @@ } } + /* (non-Javadoc) + * @see fr.cemagref.simexplorer.is.storage.database.Database#updateFilter(java.lang.String, java.util.Collection) + */ + @Override + public void updateFilter(String userFilter, Collection<String> visibleItems) throws SimExplorerTechnicalException { + if (visibleItems != null) { + Filter filter = createFilter(visibleItems); + synchronized (filterSynchronizer) { + filters.put(userFilter, filter); + } + } + } + } Modified: trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineImpl.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineImpl.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngineImpl.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -21,6 +21,7 @@ import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -59,6 +60,17 @@ /** The opened. */ private boolean opened = false; + /** + * Convert list. + * + * @param metadatas the metadatas + * + * @return the meta data[] + */ + protected MetaData[] convertList(Collection<MetaData> metadatas) { + return metadatas.toArray(new MetaData[metadatas.size()]); + } + /** Default constructor with default implementations of storage and indexing. */ public StorageEngineImpl() { this(null, null); @@ -209,8 +221,7 @@ @Override public MetaData[] getMetadatasUsedBy(String token, String uuid, Version version) throws SimExplorerException { MetaData mde = database.getElement(uuid, version); - List<MetaData> elements = database.getElementsUsedBy(mde); - return elements.toArray(new MetaData[elements.size()]); + return convertList(database.getElementsUsedBy(mde)); } /* (non-Javadoc) @@ -228,7 +239,7 @@ metadatasUsedBy.addAll(elementsUsedBy); } - return metadatasUsedBy.toArray(new MetaData[metadatasUsedBy.size()]); + return convertList(metadatasUsedBy); } /* (non-Javadoc) @@ -237,8 +248,7 @@ @Override public MetaData[] getMetadatasUsing(String token, String uuid, Version version) throws SimExplorerException { MetaData mde = database.getElement(uuid, version); - List<MetaData> elements = database.getElementsUsing(mde); - return elements.toArray(new MetaData[elements.size()]); + return convertList( database.getElementsUsing(mde)); } @Override @@ -253,7 +263,7 @@ metadatasUsing.addAll(elementsUsing); } - return metadatasUsing.toArray(new MetaData[metadatasUsing.size()]); + return convertList(metadatasUsing); } /* (non-Javadoc) @@ -279,9 +289,7 @@ SortColumn column, SortOrder sortOrder) throws SimExplorerException { List<MetaData> elements = database.findElementsByContentSearch(query, onlyLatest, indexStart, count, column, sortOrder); - MetaData[] result; - result = elements.toArray(new MetaData[elements.size()]); - return result; + return convertList(elements); } /* (non-Javadoc) @@ -290,9 +298,7 @@ public MetaData[] findElementsByType(String token, String type, boolean onlyLatest, int start, int count, SortColumn column, SortOrder sortOrder) throws SimExplorerException { List<MetaData> elements = database.findElementsByType(type, onlyLatest, start, count, column, sortOrder); - MetaData[] result; - result = elements.toArray(new MetaData[elements.size()]); - return result; + return convertList(elements); } /* (non-Javadoc) Modified: trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/grid/ElementDataSource.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/grid/ElementDataSource.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/grid/ElementDataSource.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -55,24 +55,13 @@ this.token = token; } - /** - * Build datasource without text query. - * - * @param token the token - */ - public ElementDataSource(String token) { - super(); - this.query = ""; - this.token = token; - } - /* (non-Javadoc) * @see org.apache.tapestry.grid.GridDataSource#getAvailableRows() */ public int getAvailableRows() { int result; try { - if (query.equals("")) { + if (query == null) { result = RemoteStorageService.getStorageService().findApplicationsCount(token, true); } else { result = RemoteStorageService.getStorageService().findFullTextCount(token, query, false); @@ -108,8 +97,8 @@ if (sortModel != null) { sortColumn = sortModel.getPropertyName(); } - - if (query.equals("")) { + + if (query == null) { entities = RemoteStorageService.getStorageService().findApplications(token, true, startIndex, 1 + endIndex - startIndex, sortColumn, ascending); } else { @@ -121,13 +110,4 @@ } } - /** - * Current query. - * - * @return Current text query - */ - public String getQuery() { - return query; - } - } Modified: trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/pages/ElementList.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/pages/ElementList.java 2008-02-22 16:54:05 UTC (rev 1203) +++ trunk/simexplorer-is/simexplorer-is-web/src/java/fr/cemagref/simexplorer/is/ui/web/pages/ElementList.java 2008-02-22 19:43:28 UTC (rev 1204) @@ -31,6 +31,7 @@ import fr.cemagref.simexplorer.is.entities.metadata.MetaData; import fr.cemagref.simexplorer.is.exceptions.SimExplorerException; import fr.cemagref.simexplorer.is.ui.web.grid.ElementDataSource; +import fr.cemagref.simexplorer.is.ui.web.grid.ElementDataSource; import fr.cemagref.simexplorer.is.ui.web.pages.security.UserPage; import fr.cemagref.simexplorer.is.ui.web.tools.ModelFactory; @@ -51,10 +52,6 @@ @Inject private ComponentResources resources; - /** The element data source. */ - @Persist - private ElementDataSource elementDataSource; - /** The _element. */ @SetterGetter private MetaData _element; @@ -63,12 +60,14 @@ @InjectPage private ElementDetail elementDetail; + @Persist + private String query; + /** * Page loaded. */ void pageLoaded() { model = ModelFactory.getMetaDataModel(beanModelSource, resources, true); - elementDataSource = new ElementDataSource(getToken()); } /** @@ -85,11 +84,11 @@ * * @param query the query */ - public void searchQuery(String query) { + public void searchQuery(String query) { if (query == null || query.equals("")) { - elementDataSource = new ElementDataSource(getToken()); + this.query = null; } else { - elementDataSource = new ElementDataSource(getToken(), query); + this.query = query; } } @@ -98,11 +97,8 @@ * * @return the elements */ - public ElementDataSource getElements() { - if (elementDataSource == null) { - elementDataSource = new ElementDataSource(getToken()); - } - return elementDataSource; + public ElementDataSource getElements() { + return new ElementDataSource(getToken(), this.query); } /** @@ -136,8 +132,8 @@ @Override public String getWindowTitle() { String title; - if (elementDataSource.getQuery() != null && !elementDataSource.getQuery().equals("")) { - title = getMessages().format("simexplorer.ui.web.title.searchresults", elementDataSource.getQuery()); + if (this.query != null && !this.query.equals("")) { + title = getMessages().format("simexplorer.ui.web.title.searchresults", this.query); } else { title = getMessages().get("simexplorer.ui.web.title.applicationlist"); }