Author: echatellier Date: 2013-05-21 14:36:43 +0200 (Tue, 21 May 2013) New Revision: 224 Url: http://forge.codelutin.com/projects/cantharella/repository/revisions/224 Log: fixes #2353: Moteur de recherche: Test Securit?\195?\169 > resultats sur lesquels je n'ai pas les droits... fixes #2354: Moteur de recherche: manque les r?\195?\169sultats pour Lots fixes #2355: Moteur de recherche: Pb recherche par pays fixes #2357: Moteur de recherche: Mol?\195?\169cules des r?\195?\169sultats en trop fixes #2358: Moteur de Recherche: Pb recherche par nom de Campagne fixes #2359: Moteur de recherche: recherche par pays: R?\195?\169sultats incomplets en Utilisateur / Admin fixes #2363: Gestion des droits: Pb pour donner des droits sur un lot en particulier Added: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaAnalyzer.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemFilter.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemmer.java Removed: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/HibernateSearchIntegrator.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CampagnePersonneBridge.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/IndexEventListener.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/LotPersonneBridge.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/UtilisateurSearchFilter.java Modified: trunk/cantharella.data/pom.xml trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/DataContext.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Campagne.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/CampagnePersonneDroits.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Extraction.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Lot.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/LotPersonneDroits.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Produit.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Purification.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/ResultatTestBio.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Specimen.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Station.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/TestBio.java trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/ProduitBridge.java trunk/cantharella.data/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator trunk/cantharella.data/src/main/resources/cantharella.conf trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/DocumentService.java trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/impl/SearchServiceImpl.java trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/extraction/ListExtractionsPage.java trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/station/ListStationsPage.java trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/testBio/ListTestsBioPage.java trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/utils/panels/PropertyLabelLinkProduitPanel.java Modified: trunk/cantharella.data/pom.xml =================================================================== --- trunk/cantharella.data/pom.xml 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/pom.xml 2013-05-21 12:36:43 UTC (rev 224) @@ -118,12 +118,12 @@ <artifactId>hibernate-search-engine</artifactId> </dependency> <dependency> - <groupId>org.hibernate</groupId> - <artifactId>hibernate-search-orm</artifactId> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-core</artifactId> </dependency> <dependency> <groupId>org.apache.lucene</groupId> - <artifactId>lucene-core</artifactId> + <artifactId>lucene-analyzers</artifactId> </dependency> <dependency> <groupId>c3p0</groupId> Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/DataContext.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/DataContext.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/DataContext.java 2013-05-21 12:36:43 UTC (rev 224) @@ -38,6 +38,7 @@ import javax.validation.ValidatorFactory; import nc.ird.cantharella.data.exceptions.UnexpectedException; +import nc.ird.cantharella.data.model.search.CantharellaAnalyzer; import nc.ird.cantharella.data.validation.utils.ModelValidator; import nc.ird.cantharella.data.validation.utils.ModelValidatorImpl; import nc.ird.cantharella.utils.CantharellaConfig; @@ -313,8 +314,10 @@ // Hibernate search hibernateProperties.setProperty("hibernate.search.default.directory_provider", "filesystem"); hibernateProperties.setProperty("hibernate.search.default.indexBase", hibernateSearchIndexBase); - hibernateProperties.setProperty("hibernate.search.analyzer", hibernateSearchAnalyzer); - hibernateProperties.setProperty("hibernate.search.enable_dirty_check", "false"); + hibernateProperties.setProperty(org.hibernate.search.Environment.ANALYZER_CLASS, CantharellaAnalyzer.class + .getName()); + hibernateProperties.setProperty(org.hibernate.search.Environment.ENABLE_DIRTY_CHECK, "false"); + hibernateProperties.setProperty(org.hibernate.search.Environment.LUCENE_MATCH_VERSION, "LUCENE_36"); // Hibernate: Session //hibernateProperties.setProperty("hibernate.current_session_context_class", "thread"); //hibernateProperties.setProperty(Environment.JTA_PLATFORM, "hibernate.transaction.factory_class", SpringTransactionFactory.class.getName()); Deleted: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/HibernateSearchIntegrator.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/HibernateSearchIntegrator.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/config/HibernateSearchIntegrator.java 2013-05-21 12:36:43 UTC (rev 224) @@ -1,142 +0,0 @@ -package nc.ird.cantharella.data.config; - -/* - * #%L - * Cantharella :: Data - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - -import java.util.List; - -import nc.ird.cantharella.data.model.Campagne; -import nc.ird.cantharella.data.model.CampagnePersonneDroits; -import nc.ird.cantharella.data.model.Lot; -import nc.ird.cantharella.data.model.LotPersonneDroits; -import nc.ird.cantharella.data.model.search.IndexEventListener; - -import org.hibernate.Session; -import org.hibernate.cfg.Configuration; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.event.service.spi.EventListenerRegistry; -import org.hibernate.event.spi.EventType; -import org.hibernate.event.spi.PostDeleteEvent; -import org.hibernate.event.spi.PostDeleteEventListener; -import org.hibernate.event.spi.PostInsertEvent; -import org.hibernate.event.spi.PostInsertEventListener; -import org.hibernate.event.spi.PostUpdateEvent; -import org.hibernate.event.spi.PostUpdateEventListener; -import org.hibernate.integrator.spi.Integrator; -import org.hibernate.metamodel.source.MetadataImplementor; -import org.hibernate.search.FullTextSession; -import org.hibernate.search.Search; -import org.hibernate.service.spi.SessionFactoryServiceRegistry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Register cantharella validator into hibernate using integrator. - * - * @author echatellier - */ -public class HibernateSearchIntegrator implements Integrator, PostDeleteEventListener, PostUpdateEventListener, - PostInsertEventListener { - - /** Logger */ - private static final Logger LOG = LoggerFactory.getLogger(HibernateSearchIntegrator.class); - - /** {@inheritDoc} */ - @Override - public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, - SessionFactoryServiceRegistry serviceRegistry) { - if (LOG.isDebugEnabled()) { - LOG.debug("Registering custom search listener into hibernate"); - } - - // register validator - EventListenerRegistry eventRegistry = serviceRegistry.getService(EventListenerRegistry.class); - - IndexEventListener listener = new IndexEventListener(IndexEventListener.Installation.SINGLE_INSTANCE); - eventRegistry.prependListeners(EventType.POST_DELETE, listener); - eventRegistry.prependListeners(EventType.POST_UPDATE, listener); - eventRegistry.prependListeners(EventType.POST_INSERT, listener); - listener.initialize(configuration); - } - - /** {@inheritDoc} */ - @Override - public void integrate(MetadataImplementor metadata, SessionFactoryImplementor sessionFactory, - SessionFactoryServiceRegistry serviceRegistry) { - integrate((Configuration) null, sessionFactory, serviceRegistry); - } - - /** {@inheritDoc} */ - @Override - public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { - - } - - /** {@inheritDoc} */ - @Override - public void onPostInsert(PostInsertEvent event) { - Object entity = event.getEntity(); - LOG.debug("[Event] onPostInsert on : " + entity); - reIndexEntity(event.getSession(), event.getEntity()); - } - - /** {@inheritDoc} */ - @Override - public void onPostUpdate(PostUpdateEvent event) { - Object entity = event.getEntity(); - LOG.debug("[Event] onPostUpdate on : " + entity); - reIndexEntity(event.getSession(), event.getEntity()); - } - - /** {@inheritDoc} */ - @Override - public void onPostDelete(PostDeleteEvent event) { - Object entity = event.getEntity(); - LOG.debug("[Event] onPostDelete on : " + entity); - reIndexEntity(event.getSession(), event.getEntity()); - } - - /** - * Reindex entity associated with event entity depending on - * entity type. - * - * @param session current session - * @param entity current entity - */ - protected void reIndexEntity(Session session, Object entity) { - if (entity instanceof LotPersonneDroits) { - Lot lot = ((LotPersonneDroits) entity).getId().getPk1(); - lot = (Lot) session.merge(lot); - FullTextSession fullTextSession = Search.getFullTextSession(session); - fullTextSession.index(lot); - } else if (entity instanceof CampagnePersonneDroits) { - Campagne campagne = ((CampagnePersonneDroits) entity).getId().getPk1(); - campagne = (Campagne) session.merge(campagne); - FullTextSession fullTextSession = Search.getFullTextSession(session); - List<Lot> lots = campagne.getLots(); - for (Lot lot : lots) { - fullTextSession.index(lot); - } - } - } -} Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Campagne.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Campagne.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Campagne.java 2013-05-21 12:36:43 UTC (rev 224) @@ -52,12 +52,9 @@ import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.annotations.Type; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotEmpty; @@ -142,9 +139,6 @@ /** Droits personnes */ @NotNull @OneToMany(mappedBy = "id.pk1", fetch = FetchType.LAZY) - @IndexedEmbedded - // FIXME echatellier 20130320 EAGER du to HSEARCH-1260 bug, but should be lazy fetch - @LazyCollection(LazyCollectionOption.FALSE) private List<CampagnePersonneDroits> personnesDroits; /** Stations prospectées **/ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/CampagnePersonneDroits.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/CampagnePersonneDroits.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/CampagnePersonneDroits.java 2013-05-21 12:36:43 UTC (rev 224) @@ -28,15 +28,9 @@ import javax.persistence.Table; import javax.validation.constraints.NotNull; -import nc.ird.cantharella.data.model.search.CampagnePersonneBridge; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.CompositeId; -import org.hibernate.search.annotations.ClassBridge; -import org.hibernate.search.annotations.Index; -import org.hibernate.search.annotations.IndexedEmbedded; -import org.hibernate.search.annotations.Store; - /** * Modèle : droits d'une personne sur une campagne * @author Mickael Tricot @@ -44,7 +38,6 @@ @Entity @Table @Embeddable -@ClassBridge(name = "campagne", index = Index.YES, store = Store.YES, impl = CampagnePersonneBridge.class) public class CampagnePersonneDroits extends AbstractModel { /** Droits */ @@ -54,7 +47,6 @@ /** ID */ @EmbeddedId @NotNull - @IndexedEmbedded private CompositeId<Campagne, Personne> id; /** Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Extraction.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Extraction.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Extraction.java 2013-05-21 12:36:43 UTC (rev 224) @@ -45,7 +45,6 @@ import nc.ird.cantharella.data.config.DataContext; import nc.ird.cantharella.data.model.comparators.ExtraitsOfExtractionComp; -import nc.ird.cantharella.data.model.search.UtilisateurSearchFilter; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.DocumentAttachable; @@ -56,11 +55,8 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.Type; -import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.FullTextFilterDef; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; @@ -73,7 +69,6 @@ */ @Entity @Indexed -@FullTextFilterDefs( { @FullTextFilterDef(name = "utilisateur-Extraction", impl = UtilisateurSearchFilter.class) }) public class Extraction extends AbstractModel implements Comparable<Extraction>, DocumentAttachable { /** Id de l'extraction */ @@ -85,7 +80,7 @@ @Length(max = LENGTH_MEDIUM_TEXT) @Column(unique = true) @NotEmpty - @Field(store = Store.YES, analyze = Analyze.NO) + @Field(store = Store.YES) private String ref; /** Manipulateur */ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Lot.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Lot.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Lot.java 2013-05-21 12:36:43 UTC (rev 224) @@ -46,7 +46,6 @@ import javax.validation.constraints.Past; import nc.ird.cantharella.data.config.DataContext; -import nc.ird.cantharella.data.model.search.UtilisateurSearchFilter; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.DocumentAttachable; @@ -55,13 +54,9 @@ import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.annotations.Type; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.FullTextFilterDef; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; @@ -77,7 +72,6 @@ @Table @Indexed @Embeddable -@FullTextFilterDefs( { @FullTextFilterDef(name = "utilisateur-Lot", impl = UtilisateurSearchFilter.class) }) public class Lot extends AbstractModel implements Comparable<Lot>, DocumentAttachable { /** ID */ @@ -152,9 +146,6 @@ /** Droits attribués aux personnes */ @OneToMany(mappedBy = "id.pk1", fetch = FetchType.LAZY) @NotNull - @IndexedEmbedded - // FIXME echatellier 20130320 EAGER du to HSEARCH-1260 bug, but should be lazy fetch - @LazyCollection(LazyCollectionOption.FALSE) private List<LotPersonneDroits> personnesDroits; /** Spécimen source */ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/LotPersonneDroits.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/LotPersonneDroits.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/LotPersonneDroits.java 2013-05-21 12:36:43 UTC (rev 224) @@ -28,15 +28,9 @@ import javax.persistence.Table; import javax.validation.constraints.NotNull; -import nc.ird.cantharella.data.model.search.LotPersonneBridge; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.CompositeId; -import org.hibernate.search.annotations.ClassBridge; -import org.hibernate.search.annotations.Index; -import org.hibernate.search.annotations.IndexedEmbedded; -import org.hibernate.search.annotations.Store; - /** * Modèle : droits d'une personne sur un lot * @author Mickael Tricot @@ -44,7 +38,6 @@ @Entity @Table @Embeddable -@ClassBridge(name = "lot", index = Index.YES, store = Store.YES, impl = LotPersonneBridge.class) public class LotPersonneDroits extends AbstractModel { /** Droits */ @@ -54,7 +47,6 @@ /** ID */ @EmbeddedId @NotNull - @IndexedEmbedded private CompositeId<Lot, Personne> id; /** Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Produit.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Produit.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Produit.java 2013-05-21 12:36:43 UTC (rev 224) @@ -43,7 +43,6 @@ import nc.ird.cantharella.data.model.utils.AbstractModel; import org.apache.commons.beanutils.BeanComparator; -import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.ClassBridge; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; @@ -70,7 +69,7 @@ @Length(max = LENGTH_MEDIUM_TEXT) @NotEmpty @Column(unique = true) - @Field(store = Store.YES, analyze = Analyze.NO) + @Field(store = Store.YES) private String ref; /** Masse obtenue pour le produit **/ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Purification.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Purification.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Purification.java 2013-05-21 12:36:43 UTC (rev 224) @@ -46,7 +46,6 @@ import nc.ird.cantharella.data.config.DataContext; import nc.ird.cantharella.data.model.comparators.FractionsOfPurificationComp; -import nc.ird.cantharella.data.model.search.UtilisateurSearchFilter; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.DocumentAttachable; import nc.ird.cantharella.utils.AssertTools; @@ -58,11 +57,8 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.Type; -import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.FullTextFilterDef; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; @@ -75,7 +71,6 @@ */ @Entity @Indexed -@FullTextFilterDefs( { @FullTextFilterDef(name = "utilisateur-Purification", impl = UtilisateurSearchFilter.class) }) public class Purification extends AbstractModel implements Comparable<Purification>, DocumentAttachable { /** Id de la purification */ @@ -87,7 +82,7 @@ @Length(max = LENGTH_MEDIUM_TEXT) @Column(unique = true) @NotEmpty - @Field(store = Store.YES, analyze = Analyze.NO) + @Field(store = Store.YES) private String ref; /** Manipulateur */ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/ResultatTestBio.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/ResultatTestBio.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/ResultatTestBio.java 2013-05-21 12:36:43 UTC (rev 224) @@ -38,7 +38,6 @@ import javax.validation.constraints.NotNull; import nc.ird.cantharella.data.config.DataContext; -import nc.ird.cantharella.data.model.search.UtilisateurSearchFilter; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.DocumentAttachable; import nc.ird.cantharella.data.validation.CollectionUniqueField; @@ -47,8 +46,6 @@ import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.collections.comparators.ComparatorChain; import org.hibernate.annotations.Index; -import org.hibernate.search.annotations.FullTextFilterDef; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.validator.constraints.Length; @@ -65,7 +62,6 @@ @Entity @CollectionUniqueField(fieldName = "repere", pathToCollection = "testBio.resultats") @Indexed -@FullTextFilterDefs( { @FullTextFilterDef(name = "utilisateur-ResultatTestBio", impl = UtilisateurSearchFilter.class) }) public class ResultatTestBio extends AbstractModel implements Cloneable, Comparable<ResultatTestBio>, DocumentAttachable { Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Specimen.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Specimen.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Specimen.java 2013-05-21 12:36:43 UTC (rev 224) @@ -43,7 +43,6 @@ import javax.persistence.TemporalType; import javax.validation.constraints.NotNull; -import nc.ird.cantharella.data.model.search.UtilisateurSearchFilter; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.DocumentAttachable; @@ -53,10 +52,7 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.Type; -import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.FullTextFilterDef; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; @@ -72,7 +68,6 @@ @Table @Indexed @Embeddable -@FullTextFilterDefs( { @FullTextFilterDef(name = "utilisateur-Specimen", impl = UtilisateurSearchFilter.class) }) public class Specimen extends AbstractModel implements Comparable<Specimen>, DocumentAttachable { /** @@ -104,7 +99,7 @@ @Column(unique = true) @NotEmpty @Length(max = LENGTH_TINY_TEXT) - @Field(store = Store.YES, analyze = Analyze.NO) + @Field(store = Store.YES) private String ref; /** Embranchement */ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Station.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Station.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/Station.java 2013-05-21 12:36:43 UTC (rev 224) @@ -39,7 +39,6 @@ import javax.persistence.Table; import javax.validation.constraints.NotNull; -import nc.ird.cantharella.data.model.search.UtilisateurSearchFilter; import nc.ird.cantharella.data.model.utils.AbstractModel; import nc.ird.cantharella.data.model.utils.DocumentAttachable; import nc.ird.cantharella.data.validation.CountryCode; @@ -56,8 +55,6 @@ import org.hibernate.annotations.Type; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.FullTextFilterDef; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.validator.constraints.Length; @@ -73,7 +70,6 @@ @AccessType("field") @Indexed @Embeddable -@FullTextFilterDefs( { @FullTextFilterDef(name = "utilisateur-Station", impl = UtilisateurSearchFilter.class) }) public class Station extends AbstractModel implements Cloneable, Comparable<Station>, DocumentAttachable { /** ID */ Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/TestBio.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/TestBio.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/TestBio.java 2013-05-21 12:36:43 UTC (rev 224) @@ -60,7 +60,6 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.Type; -import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.IndexedEmbedded; @@ -85,7 +84,7 @@ @Length(max = LENGTH_MEDIUM_TEXT) @Column(unique = true) @NotEmpty - @Field(store = Store.YES, analyze = Analyze.NO) + @Field(store = Store.YES) private String ref; /** Manipulateur */ Deleted: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CampagnePersonneBridge.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CampagnePersonneBridge.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CampagnePersonneBridge.java 2013-05-21 12:36:43 UTC (rev 224) @@ -1,68 +0,0 @@ -package nc.ird.cantharella.data.model.search; - -/* - * #%L - * Cantharella :: Data - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2010 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - -import nc.ird.cantharella.data.model.Campagne; -import nc.ird.cantharella.data.model.CampagnePersonneDroits; -import nc.ird.cantharella.data.model.Personne; -import nc.ird.cantharella.data.model.utils.CompositeId; - -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.hibernate.search.bridge.FieldBridge; -import org.hibernate.search.bridge.LuceneOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Hibernate search can't index CompositeId by himself. - * - * To index right on entities, we add a field "droit.pk2" containing user - * id, meaning "this user can see this indexed document". - * - * @author Eric Chatellier - */ -public class CampagnePersonneBridge implements FieldBridge { - - /** Logger */ - private static final Logger LOG = LoggerFactory.getLogger(CampagnePersonneBridge.class); - - /** {@inheritDoc} */ - @Override - public void set(String name, Object value, Document document, LuceneOptions luceneOptions) { - - CampagnePersonneDroits campagnePersonneDroits = (CampagnePersonneDroits) value; - if (LOG.isTraceEnabled()) { - LOG.trace("Custom indexing of CampagnePersonneDroits : " - + campagnePersonneDroits.getId().getPk1().getIdCampagne() + "," - + campagnePersonneDroits.getId().getPk2().getIdPersonne()); - } - - CompositeId<Campagne, Personne> compositeId = campagnePersonneDroits.getId(); - - // commons information for all produit - document.add(new Field("droit.pk2", String.valueOf(compositeId.getPk2().getIdPersonne()), luceneOptions - .getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); - } -} Added: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaAnalyzer.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaAnalyzer.java (rev 0) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaAnalyzer.java 2013-05-21 12:36:43 UTC (rev 224) @@ -0,0 +1,165 @@ +/* + * #%L + * Cantharella :: Data + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package nc.ird.cantharella.data.model.search; + +import java.io.IOException; +import java.io.Reader; +import java.util.Set; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.CharArraySet; +import org.apache.lucene.analysis.KeywordMarkerFilter; +import org.apache.lucene.analysis.LowerCaseFilter; +import org.apache.lucene.analysis.StopFilter; +import org.apache.lucene.analysis.StopwordAnalyzerBase; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.analysis.WordlistLoader; +import org.apache.lucene.analysis.fr.ElisionFilter; +import org.apache.lucene.analysis.fr.FrenchLightStemFilter; +import org.apache.lucene.analysis.snowball.SnowballFilter; +import org.apache.lucene.analysis.standard.StandardAnalyzer; // for javadoc +import org.apache.lucene.analysis.standard.StandardFilter; +import org.apache.lucene.analysis.standard.StandardTokenizer; +import org.apache.lucene.util.IOUtils; +import org.apache.lucene.util.Version; + +/** + * {@link Analyzer} for French language. + * <p> + * Supports an external list of stopwords (words that + * will not be indexed at all) and an external list of exclusions (word that will + * not be stemmed, but indexed). + * A default set of stopwords is used unless an alternative list is specified, but the + * exclusion list is empty by default. + * </p> + * + * <a name="version"/> + * <p>You must specify the required {@link Version} + * compatibility when creating FrenchAnalyzer: + * <ul> + * <li> As of 3.6, FrenchLightStemFilter is used for less aggressive stemming. + * <li> As of 3.1, Snowball stemming is done with SnowballFilter, + * LowerCaseFilter is used prior to StopFilter, and ElisionFilter and + * Snowball stopwords are used by default. + * <li> As of 2.9, StopFilter preserves position + * increments + * </ul> + * + * <p><b>NOTE</b>: This class uses the same {@link Version} + * dependent settings as {@link StandardAnalyzer}.</p> + */ +public final class CantharellaAnalyzer extends StopwordAnalyzerBase { + + /** File containing default French stopwords. */ + public final static String DEFAULT_STOPWORD_FILE = "french_stop.txt"; + + /** + * Contains words that should be indexed but not stemmed. + */ + private Set<?> excltable = CharArraySet.EMPTY_SET; + + /** + * Returns an unmodifiable instance of the default stop-words set. + * @return an unmodifiable instance of the default stop-words set. + */ + public static Set<?> getDefaultStopSet() { + return DefaultSetHolder.DEFAULT_STOP_SET; + } + + @SuppressWarnings("deprecation") + private static class DefaultSetHolder { + + static final Set<?> DEFAULT_STOP_SET; + static { + try { + DEFAULT_STOP_SET = WordlistLoader.getSnowballWordSet(IOUtils.getDecodingReader(SnowballFilter.class, + DEFAULT_STOPWORD_FILE, IOUtils.CHARSET_UTF_8), Version.LUCENE_CURRENT); + } catch (IOException ex) { + // default set should always be present as it is part of the + // distribution (JAR) + throw new RuntimeException("Unable to load default stopword set"); + } + } + } + + /** + * Builds an analyzer with the default stop words ({@link #getDefaultStopSet}). + * @param matchVersion lucene match version + */ + public CantharellaAnalyzer(Version matchVersion) { + this(matchVersion, DefaultSetHolder.DEFAULT_STOP_SET); + } + + /** + * Builds an analyzer with the given stop words + * + * @param matchVersion + * lucene compatibility version + * @param stopwords + * a stopword set + */ + public CantharellaAnalyzer(Version matchVersion, Set<?> stopwords) { + this(matchVersion, stopwords, CharArraySet.EMPTY_SET); + } + + /** + * Builds an analyzer with the given stop words + * + * @param matchVersion + * lucene compatibility version + * @param stopwords + * a stopword set + * @param stemExclutionSet + * a stemming exclusion set + */ + public CantharellaAnalyzer(Version matchVersion, Set<?> stopwords, Set<?> stemExclutionSet) { + super(matchVersion, stopwords); + this.excltable = CharArraySet.unmodifiableSet(CharArraySet.copy(matchVersion, stemExclutionSet)); + } + + /** + * Creates + * {@link org.apache.lucene.analysis.ReusableAnalyzerBase.TokenStreamComponents} + * used to tokenize all the text in the provided {@link Reader}. + * + * @return {@link org.apache.lucene.analysis.ReusableAnalyzerBase.TokenStreamComponents} + * built from a {@link StandardTokenizer} filtered with + * {@link StandardFilter}, {@link ElisionFilter}, + * {@link LowerCaseFilter}, {@link StopFilter}, + * {@link KeywordMarkerFilter} if a stem exclusion set is + * provided, and {@link FrenchLightStemFilter} + */ + @Override + protected TokenStreamComponents createComponents(String fieldName, Reader reader) { + final Tokenizer source = new StandardTokenizer(matchVersion, reader); + TokenStream result = new StandardFilter(matchVersion, source); + result = new ElisionFilter(matchVersion, result); + result = new LowerCaseFilter(matchVersion, result); + result = new StopFilter(matchVersion, result, stopwords); + if (!excltable.isEmpty()) + result = new KeywordMarkerFilter(result, excltable); + result = new CantharellaStemFilter(result); + return new TokenStreamComponents(source, result); + } +} Property changes on: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaAnalyzer.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemFilter.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemFilter.java (rev 0) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemFilter.java 2013-05-21 12:36:43 UTC (rev 224) @@ -0,0 +1,72 @@ +/* + * #%L + * Cantharella :: Data + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package nc.ird.cantharella.data.model.search; + +import java.io.IOException; + +import org.apache.lucene.analysis.TokenFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; +import org.apache.lucene.analysis.tokenattributes.KeywordAttribute; + +/** + * Custom stem filter to use {@link CantharellaStemmer} instead of lucene's + * default French Stemmer. + * + * @author Eric Chatellier + */ +public class CantharellaStemFilter extends TokenFilter { + /** Character sequence stemmer. */ + private final CantharellaStemmer stemmer = new CantharellaStemmer(); + + /** Char term attribute. */ + private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); + + /** Keyword attribute. */ + private final KeywordAttribute keywordAttr = addAttribute(KeywordAttribute.class); + + /** + * Constructor. + * + * @param input token stream. + */ + public CantharellaStemFilter(TokenStream input) { + super(input); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean incrementToken() throws IOException { + if (input.incrementToken()) { + if (!keywordAttr.isKeyword()) { + final int newlen = stemmer.stem(termAtt.buffer(), termAtt.length()); + termAtt.setLength(newlen); + } + return true; + } else { + return false; + } + } +} \ No newline at end of file Property changes on: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemFilter.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemmer.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemmer.java (rev 0) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemmer.java 2013-05-21 12:36:43 UTC (rev 224) @@ -0,0 +1,260 @@ +/* + * #%L + * Cantharella :: Data + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package nc.ird.cantharella.data.model.search; + +import static org.apache.lucene.analysis.util.StemmerUtil.*; + +/** + * Light Stemmer for French. + * <p> + * This stemmer implements the "UniNE" algorithm in: + * <i>Light Stemming Approaches for the French, Portuguese, German and Hungarian Languages</i> + * Jacques Savoy + */ +public class CantharellaStemmer { + + /** + * Stem a char sequence. + * + * @param s char sequence to stem + * @param len char sequence length + * @return char sequence final length + */ + public int stem(char s[], int len) { + if (len > 5 && s[len - 1] == 'x') { + if (s[len - 3] == 'a' && s[len - 2] == 'u' && s[len - 4] != 'e') + s[len - 2] = 'l'; + len--; + } + + if (len > 3 && s[len - 1] == 'x') + len--; + + if (len > 3 && s[len - 1] == 's') + len--; + + if (len > 9 && endsWith(s, len, "issement")) { + len -= 6; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 8 && endsWith(s, len, "issant")) { + len -= 4; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 6 && endsWith(s, len, "ement")) { + len -= 4; + if (len > 3 && endsWith(s, len, "ive")) { + len--; + s[len - 1] = 'f'; + } + return norm(s, len); + } + + if (len > 11 && endsWith(s, len, "ficatrice")) { + len -= 5; + s[len - 2] = 'e'; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 10 && endsWith(s, len, "ficateur")) { + len -= 4; + s[len - 2] = 'e'; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 9 && endsWith(s, len, "catrice")) { + len -= 3; + s[len - 4] = 'q'; + s[len - 3] = 'u'; + s[len - 2] = 'e'; + //s[len-1] = 'r' <-- unnecessary, already 'r'. + return norm(s, len); + } + + if (len > 8 && endsWith(s, len, "cateur")) { + len -= 2; + s[len - 4] = 'q'; + s[len - 3] = 'u'; + s[len - 2] = 'e'; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 8 && endsWith(s, len, "atrice")) { + len -= 4; + s[len - 2] = 'e'; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 7 && endsWith(s, len, "ateur")) { + len -= 3; + s[len - 2] = 'e'; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 6 && endsWith(s, len, "trice")) { + len--; + s[len - 3] = 'e'; + s[len - 2] = 'u'; + s[len - 1] = 'r'; + } + + if (len > 5 && endsWith(s, len, "ième")) + return norm(s, len - 4); + + if (len > 7 && endsWith(s, len, "teuse")) { + len -= 2; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 6 && endsWith(s, len, "teur")) { + len--; + s[len - 1] = 'r'; + return norm(s, len); + } + + if (len > 5 && endsWith(s, len, "euse")) + return norm(s, len - 2); + + if (len > 8 && endsWith(s, len, "ère")) { + len--; + s[len - 2] = 'e'; + return norm(s, len); + } + + if (len > 7 && endsWith(s, len, "ive")) { + len--; + s[len - 1] = 'f'; + return norm(s, len); + } + + if (len > 4 && (endsWith(s, len, "folle") || endsWith(s, len, "molle"))) { + len -= 2; + s[len - 1] = 'u'; + return norm(s, len); + } + + if (len > 9 && endsWith(s, len, "nnelle")) + return norm(s, len - 5); + + if (len > 9 && endsWith(s, len, "nnel")) + return norm(s, len - 3); + + if (len > 4 && endsWith(s, len, "ète")) { + len--; + s[len - 2] = 'e'; + } + + if (len > 8 && endsWith(s, len, "ique")) + len -= 4; + + if (len > 8 && endsWith(s, len, "esse")) + return norm(s, len - 3); + + if (len > 7 && endsWith(s, len, "inage")) + return norm(s, len - 3); + + if (len > 9 && endsWith(s, len, "isation")) { + len -= 7; + if (len > 5 && endsWith(s, len, "ual")) + s[len - 2] = 'e'; + return norm(s, len); + } + + if (len > 9 && endsWith(s, len, "isateur")) + return norm(s, len - 7); + + if (len > 8 && endsWith(s, len, "ation")) + return norm(s, len - 5); + + if (len > 8 && endsWith(s, len, "ition")) + return norm(s, len - 5); + + return norm(s, len); + } + + private int norm(char s[], int len) { + if (len > 4) { + for (int i = 0; i < len; i++) + switch (s[i]) { + case 'à': + case 'á': + case 'â': + s[i] = 'a'; + break; + case 'ô': + s[i] = 'o'; + break; + case 'è': + case 'é': + case 'ê': + s[i] = 'e'; + break; + case 'ù': + case 'û': + s[i] = 'u'; + break; + case 'î': + s[i] = 'i'; + break; + case 'ç': + s[i] = 'c'; + break; + } + + /* XXX chatellier 20130516 disabled for cantharella because + duplicated characters are usefull in some refs identifiers + char ch = s[0]; + for (int i = 1; i < len; i++) { + if (s[i] == ch) + len = delete(s, i--, len); + else + ch = s[i]; + }*/ + } + + if (len > 4 && endsWith(s, len, "ie")) + len -= 2; + + if (len > 4) { + if (s[len - 1] == 'r') + len--; + if (s[len - 1] == 'e') + len--; + if (s[len - 1] == 'e') + len--; + if (s[len - 1] == s[len - 2]) + len--; + } + return len; + } +} Property changes on: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/CantharellaStemmer.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Deleted: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/IndexEventListener.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/IndexEventListener.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/IndexEventListener.java 2013-05-21 12:36:43 UTC (rev 224) @@ -1,112 +0,0 @@ -/* - * #%L - * Cantharella :: Data - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2012 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package nc.ird.cantharella.data.model.search; - -import java.io.Serializable; - -import nc.ird.cantharella.data.model.Campagne; -import nc.ird.cantharella.data.model.CampagnePersonneDroits; -import nc.ird.cantharella.data.model.Lot; -import nc.ird.cantharella.data.model.LotPersonneDroits; -import nc.ird.cantharella.data.model.Personne; -import nc.ird.cantharella.data.model.utils.CompositeId; - -import org.hibernate.Session; -import org.hibernate.event.spi.AbstractEvent; -import org.hibernate.event.spi.PostDeleteEvent; -import org.hibernate.event.spi.PostInsertEvent; -import org.hibernate.event.spi.PostUpdateEvent; -import org.hibernate.search.backend.spi.WorkType; -import org.hibernate.search.event.impl.FullTextIndexEventListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Hibernate event listener to force reindexation on custom indexed entity: - * {@link LotPersonneDroits} and {@link CampagnePersonneDroits}. - * - * @author Eric Chatellier - */ -public class IndexEventListener extends FullTextIndexEventListener { - - /** Logger */ - private static final Logger LOG = LoggerFactory.getLogger(IndexEventListener.class); - - /** - * Constructor. - * @param installation installation strategy - */ - public IndexEventListener(Installation installation) { - super(installation); - } - - /** {@inheritDoc}. */ - @Override - public void onPostDelete(PostDeleteEvent event) { - Object entity = event.getEntity(); - LOG.debug("[Event] onPostDelete on : " + entity); - reIndexEntity(event, event.getEntity(), event.getId()); - } - - /** {@inheritDoc}. */ - @Override - public void onPostInsert(PostInsertEvent event) { - Object entity = event.getEntity(); - LOG.debug("[Event] onPostInsert on : " + entity); - reIndexEntity(event, event.getEntity(), event.getId()); - } - - /** {@inheritDoc}. */ - @Override - public void onPostUpdate(PostUpdateEvent event) { - Object entity = event.getEntity(); - LOG.debug("[Event] onPostUpdate on : " + entity); - reIndexEntity(event, event.getEntity(), event.getId()); - } - - /** - * Reindex entity associated with event entity depending on - * entity type. - * - * @param event event - * @param entity current entity - * @param id entity id - */ - @SuppressWarnings("unchecked") - protected void reIndexEntity(AbstractEvent event, Object entity, Serializable id) { - Session session = event.getSession(); - if (entity instanceof LotPersonneDroits) { - Lot lot = ((CompositeId<Lot, Personne>) id).getPk1(); - // must do refresh to avoid lazy or no entity with given identifier - // exception - session.refresh(lot); - super.processWork(lot, lot.getIdLot(), WorkType.INDEX, event, false); - } else if (entity instanceof CampagnePersonneDroits) { - Campagne campagne = ((CompositeId<Campagne, Personne>) id).getPk1(); - // must do refresh to avoid lazy or no entity with given identifier - // exception - session.refresh(campagne); - super.processWork(campagne, campagne.getIdCampagne(), WorkType.INDEX, event, false); - } - } -} Deleted: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/LotPersonneBridge.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/LotPersonneBridge.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/LotPersonneBridge.java 2013-05-21 12:36:43 UTC (rev 224) @@ -1,67 +0,0 @@ -package nc.ird.cantharella.data.model.search; - -/* - * #%L - * Cantharella :: Data - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2010 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - -import nc.ird.cantharella.data.model.Lot; -import nc.ird.cantharella.data.model.LotPersonneDroits; -import nc.ird.cantharella.data.model.Personne; -import nc.ird.cantharella.data.model.utils.CompositeId; - -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.hibernate.search.bridge.FieldBridge; -import org.hibernate.search.bridge.LuceneOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Hibernate search can't index CompositeId by himself. - * - * To index right on entities, we add a field "droit.pk2" containing user - * id, meaning "this user can see this indexed document". - * - * @author Eric Chatellier - */ -public class LotPersonneBridge implements FieldBridge { - - /** Logger */ - private static final Logger LOG = LoggerFactory.getLogger(LotPersonneBridge.class); - - /** {@inheritDoc} */ - @Override - public void set(String name, Object value, Document document, LuceneOptions luceneOptions) { - - LotPersonneDroits lotPersonneDroits = (LotPersonneDroits) value; - if (LOG.isTraceEnabled()) { - LOG.trace("Custom indexing of LotPersonneDroits : " + lotPersonneDroits.getId().getPk1().getIdLot() + "," - + lotPersonneDroits.getId().getPk2().getIdPersonne()); - } - - CompositeId<Lot, Personne> compositeId = lotPersonneDroits.getId(); - - // commons information for all produit - document.add(new Field("droit.pk2", String.valueOf(compositeId.getPk2().getIdPersonne()), luceneOptions - .getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); - } -} Modified: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/ProduitBridge.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/ProduitBridge.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/ProduitBridge.java 2013-05-21 12:36:43 UTC (rev 224) @@ -23,13 +23,9 @@ * #L% */ -import java.util.List; - -import nc.ird.cantharella.data.model.CampagnePersonneDroits; import nc.ird.cantharella.data.model.Extrait; import nc.ird.cantharella.data.model.Fraction; import nc.ird.cantharella.data.model.Lot; -import nc.ird.cantharella.data.model.LotPersonneDroits; import nc.ird.cantharella.data.model.Produit; import nc.ird.cantharella.data.model.ResultatTestBio; @@ -62,8 +58,6 @@ } // commons information for all produit - //document.add(new Field("produit.ref", produit.getRef(), luceneOptions.getStore(), luceneOptions.getIndex(), - // luceneOptions.getTermVector())); Lot lot = null; if (produit instanceof Extrait) { if (LOG.isTraceEnabled()) { @@ -79,28 +73,33 @@ lot = fraction.getPurification().getLotSource(); } - document.add(new Field("produit.lot.ref", lot.getRef(), luceneOptions.getStore(), luceneOptions.getIndex(), + // ref field tokenized with a non fr analyzer + // to avoid duplicated letter removal (00) + document.add(new Field(name + ".lot.ref", lot.getRef(), luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); - document.add(new Field("produit.lot.speciment.embranchement", lot.getSpecimenRef().getEmbranchement(), - luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); + + if (StringUtils.isNotBlank(lot.getSpecimenRef().getEmbranchement())) { + document.add(new Field(name + ".lot.specimen.embranchement", lot.getSpecimenRef().getEmbranchement(), + luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); + } if (StringUtils.isNotBlank(lot.getSpecimenRef().getFamille())) { - document.add(new Field("produit.lot.speciment.famille", lot.getSpecimenRef().getFamille(), luceneOptions + document.add(new Field(name + ".lot.specimen.famille", lot.getSpecimenRef().getFamille(), luceneOptions .getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); } if (StringUtils.isNotBlank(lot.getSpecimenRef().getGenre())) { - document.add(new Field("produit.lot.speciment.genre", lot.getSpecimenRef().getGenre(), luceneOptions + document.add(new Field(name + ".lot.specimen.genre", lot.getSpecimenRef().getGenre(), luceneOptions .getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); } if (StringUtils.isNotBlank(lot.getSpecimenRef().getEspece())) { - document.add(new Field("produit.lot.speciment.espece", lot.getSpecimenRef().getEspece(), luceneOptions + document.add(new Field(name + ".lot.specimen.espece", lot.getSpecimenRef().getEspece(), luceneOptions .getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); } - document.add(new Field("produit.lot.campagne.nom", lot.getCampagne().getNom(), luceneOptions.getStore(), + document.add(new Field(name + ".lot.campagne.nom", lot.getCampagne().getNom(), luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); - document.add(new Field("produit.lot.campagne.codePays", lot.getCampagne().getCodePays(), luceneOptions + document.add(new Field(name + ".lot.campagne.codePays", lot.getCampagne().getCodePays(), luceneOptions .getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); - // commons information for all produit + /* commons information for all produit List<LotPersonneDroits> personnesDroits = lot.getPersonnesDroits(); for (LotPersonneDroits lotPersonneDroit : personnesDroits) { document.add(new Field("droit.pk2", String.valueOf(lotPersonneDroit.getId().getPk2().getIdPersonne()), @@ -110,6 +109,6 @@ for (CampagnePersonneDroits campagnesDroit : campagnesDroits) { document.add(new Field("droit.pk2", String.valueOf(campagnesDroit.getId().getPk2().getIdPersonne()), luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector())); - } + }*/ } } Deleted: trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/UtilisateurSearchFilter.java =================================================================== --- trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/UtilisateurSearchFilter.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/java/nc/ird/cantharella/data/model/search/UtilisateurSearchFilter.java 2013-05-21 12:36:43 UTC (rev 224) @@ -1,129 +0,0 @@ -/* - * #%L - * Cantharella :: Data - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2013 IRD (Institut de Recherche pour le Developpement) and by respective authors (see below) - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package nc.ird.cantharella.data.model.search; - -import java.io.IOException; - -import nc.ird.cantharella.data.model.Utilisateur; -import nc.ird.cantharella.data.model.Utilisateur.TypeDroit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.Term; -import org.apache.lucene.index.TermDocs; -import org.apache.lucene.search.DocIdSet; -import org.apache.lucene.search.Filter; -import org.apache.lucene.util.OpenBitSet; -import org.hibernate.search.annotations.Key; -import org.hibernate.search.filter.FilterKey; -import org.hibernate.search.filter.StandardFilterKey; - -/** - * Filtre lucene utilisé par hibernate search pour filtrer les resultats - * suivant l'utilisateur connecté. - * - * @author Eric Chatellier - */ -public class UtilisateurSearchFilter extends Filter { - - /** serialVersionUID.*/ - private static final long serialVersionUID = 5599764509232575010L; - - /** Logger */ - private static final Logger LOG = LoggerFactory.getLogger(UtilisateurSearchFilter.class); - - /** Utilisateur performing the query. */ - protected Utilisateur utilisateur; - - /** - * Utilisateur getter. - * - * @return utilisateur - */ - public Utilisateur getUtilisateur() { - return utilisateur; - } - - /** - * Utilisateur setter. - * - * @param utilisateur utilisateur - */ - public void setUtilisateur(Utilisateur utilisateur) { - this.utilisateur = utilisateur; - } - - /** - * Return filter parameters key. - * - * @return filter parameters - */ - @Key - public FilterKey getKey() { - StandardFilterKey key = new StandardFilterKey(); - key.addParameter(utilisateur); - return key; - } - - /** {@inheritDoc} */ - @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - OpenBitSet bitSet = new OpenBitSet(reader.maxDoc()); - - if (utilisateur.getTypeDroit() == TypeDroit.ADMINISTRATEUR) { - if (LOG.isDebugEnabled()) { - LOG.debug("Filtering term docs for administrator"); - } - // all docs - for (int idx = 0; idx < reader.maxDoc(); idx++) { - if (!reader.isDeleted(idx)) { - bitSet.set(idx); - } - } - } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Filtering term docs for utilisateur"); - } - // only docs where user is creator - TermDocs termDocsCreateur = reader.termDocs(new Term("createur.idPersonne", String.valueOf(utilisateur - .getIdPersonne()))); - while (termDocsCreateur.next()) { - if (!reader.isDeleted(termDocsCreateur.doc())) { - bitSet.set(termDocsCreateur.doc()); - } - } - - // and docs where user has rights on - TermDocs termDocsDroits = reader - .termDocs(new Term("droit.pk2", String.valueOf(utilisateur.getIdPersonne()))); - while (termDocsDroits.next()) { - if (!reader.isDeleted(termDocsCreateur.doc())) { - bitSet.set(termDocsDroits.doc()); - } - } - } - - return bitSet; - } -} Modified: trunk/cantharella.data/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator =================================================================== --- trunk/cantharella.data/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator 2013-05-21 12:36:43 UTC (rev 224) @@ -1,2 +1 @@ -nc.ird.cantharella.data.config.ValidationIntegrator -nc.ird.cantharella.data.config.HibernateSearchIntegrator \ No newline at end of file +nc.ird.cantharella.data.config.ValidationIntegrator \ No newline at end of file Modified: trunk/cantharella.data/src/main/resources/cantharella.conf =================================================================== --- trunk/cantharella.data/src/main/resources/cantharella.conf 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.data/src/main/resources/cantharella.conf 2013-05-21 12:36:43 UTC (rev 224) @@ -35,4 +35,4 @@ # Hibernate search lucene index location on filesystem. hibernate.search.indexBase=/tmp/cantharella # Hibernate search analyzer -hibernate.search.analyzer=org.apache.lucene.analysis.fr.FrenchAnalyzer \ No newline at end of file +hibernate.search.analyzer=org.apache.lucene.analysis.fr.FrenchAnalyzer Modified: trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/DocumentService.java =================================================================== --- trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/DocumentService.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/DocumentService.java 2013-05-21 12:36:43 UTC (rev 224) @@ -27,10 +27,8 @@ import nc.ird.cantharella.data.exceptions.DataConstraintException; import nc.ird.cantharella.data.exceptions.DataNotFoundException; import nc.ird.cantharella.data.model.Document; -import nc.ird.cantharella.data.model.Lot; import nc.ird.cantharella.data.model.TypeDocument; import nc.ird.cantharella.data.model.Utilisateur; -import nc.ird.cantharella.data.model.Utilisateur.TypeDroit; import nc.ird.cantharella.data.model.utils.DocumentAttachable; import nc.ird.cantharella.service.exceptions.InvalidFileExtensionException; import nc.ird.cantharella.service.utils.normalizers.TypeDocumentNormalizer; Modified: trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/impl/SearchServiceImpl.java =================================================================== --- trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/impl/SearchServiceImpl.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.service/src/main/java/nc/ird/cantharella/service/services/impl/SearchServiceImpl.java 2013-05-21 12:36:43 UTC (rev 224) @@ -24,11 +24,14 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Set; import javax.annotation.Resource; import nc.ird.cantharella.data.exceptions.UnexpectedException; +import nc.ird.cantharella.data.model.Campagne; import nc.ird.cantharella.data.model.Extraction; import nc.ird.cantharella.data.model.Lot; import nc.ird.cantharella.data.model.Molecule; @@ -37,10 +40,15 @@ import nc.ird.cantharella.data.model.Specimen; import nc.ird.cantharella.data.model.Station; import nc.ird.cantharella.data.model.Utilisateur; +import nc.ird.cantharella.data.model.Utilisateur.TypeDroit; import nc.ird.cantharella.service.model.SearchBean; import nc.ird.cantharella.service.model.SearchResult; +import nc.ird.cantharella.service.services.LotService; import nc.ird.cantharella.service.services.SearchService; +import nc.ird.cantharella.service.services.SpecimenService; +import nc.ird.cantharella.service.services.StationService; +import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryParser.MultiFieldQueryParser; @@ -52,15 +60,14 @@ import org.apache.lucene.util.Version; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.search.FullTextFilter; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.MassIndexer; import org.hibernate.search.Search; import org.hibernate.search.SearchFactory; -import org.hibernate.search.annotations.FullTextFilterDefs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -78,6 +85,18 @@ @Resource private SessionFactory sessionFactory; + /** Lot service for permissions **/ + @Autowired + private LotService lotService; + + /** Station service for permissions **/ + @Autowired + private StationService stationService; + + /** Specimen service for permission **/ + @Autowired + private SpecimenService specimenService; + /** {@inheritDoc} */ @Override public void reIndex() { @@ -90,6 +109,8 @@ FullTextSession fullTextSession = Search.getFullTextSession(session); try { MassIndexer indexer = fullTextSession.createIndexer(); + indexer.batchSizeToLoadObjects(1); + indexer.threadsToLoadObjects(1); indexer.threadsForSubsequentFetching(1); indexer.startAndWait(); @@ -172,6 +193,9 @@ result.setStations(resultatStations); result.setMolecules(resultatMolecules); + // security manually managed + result = filterResults(result, utilisateur); + } catch (ParseException ex) { throw new UnexpectedException("Can't parse query", ex); } @@ -206,12 +230,13 @@ String fieldName = fieldInfos.fieldName(i); // il semble impossible de ne pas recuperer l'id du document // on l'exclut donc manuellement - if (!fieldName.startsWith("id") && !fieldName.contains(".id") && !fieldName.endsWith(".pk2")) { - fieldList.add(fieldInfos.fieldName(i)); + if (!fieldName.startsWith("id") && !fieldName.contains(".id") /*&& !fieldName.endsWith(".pk2")*/) { + fieldList.add(fieldName); } } + Analyzer analyzer = searchFactory.getAnalyzer(clazz); QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_36, fieldList.toArray(new String[fieldList.size()]), - searchFactory.getAnalyzer(clazz)); + analyzer); searchFactory.getIndexReaderAccessor().close(reader); // autorisation de "*" en premier caractere @@ -224,12 +249,79 @@ // convert lucene query to hibernate query FullTextQuery hibQuery = fullTextSession.createFullTextQuery(query, clazz); - // add security filter (if class has filter defined) - if (clazz.getAnnotation(FullTextFilterDefs.class) != null) { - FullTextFilter filter = hibQuery.enableFullTextFilter("utilisateur-" + clazz.getSimpleName()); - filter.setParameter("utilisateur", utilisateur); + return hibQuery; + } + + /** + * Iterate over all results and remove those that user is not allowed to see. + * + * @see Utilisateur#getLotsDroits() + * @see Utilisateur#getCampagnesDroits() + */ + private SearchResult filterResults(SearchResult result, Utilisateur utilisateur) { + + // no filtering + if (utilisateur.getTypeDroit() == TypeDroit.ADMINISTRATEUR) { + return result; } - return hibQuery; + // get campagnes and lots data to manage rigths + List<Campagne> campagnes = new ArrayList<Campagne>(); + campagnes.addAll(utilisateur.getCampagnesCreees()); + campagnes.addAll(utilisateur.getCampagnesDroits().keySet()); + List<Lot> lots = new ArrayList<Lot>(); + lots.addAll(utilisateur.getLotsCrees()); + lots.addAll(utilisateur.getLotsDroits().keySet()); + + // SearchResult#lots + Iterator<Lot> itLots = result.getLots().iterator(); + while (itLots.hasNext()) { + Lot lot = itLots.next(); + if (!lotService.isLotAccessibleByUser(lot, utilisateur)) { + itLots.remove(); + } + } + + // SearchResult#extractions + Iterator<Extraction> itExtractions = result.getExtractions().iterator(); + while (itExtractions.hasNext()) { + Extraction extraction = itExtractions.next(); + Lot lot = extraction.getLot(); + if (!lotService.isLotAccessibleByUser(lot, utilisateur)) { + itExtractions.remove(); + } + } + + // SearchResult#purifications + Iterator<Purification> itPurifications = result.getPurifications().iterator(); + while (itPurifications.hasNext()) { + Purification purification = itPurifications.next(); + Lot lot = purification.getLotSource(); + if (!lotService.isLotAccessibleByUser(lot, utilisateur)) { + itPurifications.remove(); + } + } + + // SearchResult#resultatTestBios + Iterator<ResultatTestBio> itResultatTestBios = result.getResultatTestBios().iterator(); + while (itResultatTestBios.hasNext()) { + ResultatTestBio resultatTestBio = itResultatTestBios.next(); + Lot lot = resultatTestBio.getLotSource(); + if (!lotService.isLotAccessibleByUser(lot, utilisateur)) { + itResultatTestBios.remove(); + } + } + + // SearchResult#stations + Set<Station> userStations = stationService.listStationsForUser(utilisateur); + result.getStations().retainAll(userStations); + + // SearchResult#specimens + Set<Specimen> userSpecimens = specimenService.listSpecimensForUser(utilisateur); + result.getSpecimens().retainAll(userSpecimens); + + // SearchResult#molecules : all visible, no filtering + + return result; } } Modified: trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/extraction/ListExtractionsPage.java =================================================================== --- trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/extraction/ListExtractionsPage.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/extraction/ListExtractionsPage.java 2013-05-21 12:36:43 UTC (rev 224) @@ -54,7 +54,6 @@ import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; import org.apache.wicket.spring.injection.annot.SpringBean; /** Modified: trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/station/ListStationsPage.java =================================================================== --- trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/station/ListStationsPage.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/station/ListStationsPage.java 2013-05-21 12:36:43 UTC (rev 224) @@ -51,7 +51,6 @@ import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; import org.apache.wicket.spring.injection.annot.SpringBean; /** Modified: trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/testBio/ListTestsBioPage.java =================================================================== --- trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/testBio/ListTestsBioPage.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/pages/domain/testBio/ListTestsBioPage.java 2013-05-21 12:36:43 UTC (rev 224) @@ -61,7 +61,6 @@ import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; import org.apache.wicket.spring.injection.annot.SpringBean; /** Modified: trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/utils/panels/PropertyLabelLinkProduitPanel.java =================================================================== --- trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/utils/panels/PropertyLabelLinkProduitPanel.java 2013-05-21 09:32:37 UTC (rev 223) +++ trunk/cantharella.web/src/main/java/nc/ird/cantharella/web/utils/panels/PropertyLabelLinkProduitPanel.java 2013-05-21 12:36:43 UTC (rev 224) @@ -32,7 +32,6 @@ import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; /** * Panel which display a "produit" link with inside the correspondig value of the model. If the produit is an Extrait,