Index: main/plugin-odf-web/i18n/messages_en.xml =================================================================== --- main/plugin-odf-web/i18n/messages_en.xml (revision 36748) +++ main/plugin-odf-web/i18n/messages_en.xml (working copy) @@ -98,6 +98,8 @@ <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_COURSE_REFERENCING_PROGRAMS_INTRO">Program(s) integrating the course: </message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_CATALOG">Catalog</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_CATALOG_DESC">The search will be based on the selected catalog</message> + <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_SUBPROGRAM">Enable search in subprograms</message> + <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_SUBPROGRAM_DESC">If subprograms search is enabled, keywords search will be enable on subprograms data too</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_FACET">Enable faceted search</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_FACET_DESC">If faceted search is enabled, choice list criteria display the number of results for each value, and will be refined as values are selected.</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_GROUP_ID">Service identifier</message> Index: main/plugin-odf-web/i18n/messages_fr.xml =================================================================== --- main/plugin-odf-web/i18n/messages_fr.xml (revision 36748) +++ main/plugin-odf-web/i18n/messages_fr.xml (working copy) @@ -98,6 +98,8 @@ <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_COURSE_REFERENCING_PROGRAMS_INTRO">Formation(s) intégrant cette UE: </message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_CATALOG">Catalogue</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_CATALOG_DESC">Catalogue des formations recherchées</message> + <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_SUBPROGRAM">Rechercher dans les parcours</message> + <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_SUBPROGRAM_DESC">Si la recherche dans les parcours est activé, la recherche de mots clefs se fera également dans les données des parcours</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_FACET">Recherche àfacettes</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_FACET_DESC">Si les facettes sont activées, les critères listes àchoix afficheront le nombre de résultats entre parenthèses, et s'affineront au fur et àmesure de la sélection des critères.</message> <message key="PLUGINS_ODFWEB_SERVICE_SEARCH_GROUP_ID">Identifiant du service</message> Index: main/plugin-odf-web/plugin.xml =================================================================== --- main/plugin-odf-web/plugin.xml (revision 36748) +++ main/plugin-odf-web/plugin.xml (working copy) @@ -392,6 +392,10 @@ <mandatory/> </validation> </parameter> + <parameter name="subprogram-search" type="boolean"> + <label i18n="true">PLUGINS_ODFWEB_SERVICE_SEARCH_SUBPROGRAM</label> + <description i18n="true">PLUGINS_ODFWEB_SERVICE_SEARCH_SUBPROGRAM_DESC</description> + </parameter> <parameter name="facets" type="boolean"> <label i18n="true">PLUGINS_ODFWEB_SERVICE_SEARCH_FACET</label> <description i18n="true">PLUGINS_ODFWEB_SERVICE_SEARCH_FACET_DESC</description> @@ -1041,6 +1045,9 @@ <components> <component role="org.ametys.odf.contenttype.ODFMetadataIndexer" class="org.ametys.plugins.odfweb.WebODFMetadataIndexer"/> + + <component role="org.ametys.odf.contenttype.SubProgramMetadataIndexer" + class="org.ametys.plugins.odfweb.WebSubProgramMetadataIndexer"/> </components> </feature> </plugin> Index: main/plugin-odf-web/sitemap.xmap =================================================================== --- main/plugin-odf-web/sitemap.xmap (revision 36748) +++ main/plugin-odf-web/sitemap.xmap (working copy) @@ -111,6 +111,7 @@ <map:generate type="odf-search"> <map:parameter name="offset" value="{parent-context-attr:offset}"/> <map:parameter name="fields" value="{parent-context-attr:search-fields}"/> + <map:parameter name="subprograms" value="{parent-context-attr:subprogram-search}"/> <map:parameter name="facets" value="{parent-context-attr:facets}"/> <map:parameter name="catalog" value="{request-param:catalog}"/> <map:parameter name="service-group-id" value="{parent-context-attr:service-group-id}"/> Index: main/plugin-odf-web/src/org/ametys/plugins/odfweb/WebSubProgramMetadataIndexer.java =================================================================== --- main/plugin-odf-web/src/org/ametys/plugins/odfweb/WebSubProgramMetadataIndexer.java (revision 0) +++ main/plugin-odf-web/src/org/ametys/plugins/odfweb/WebSubProgramMetadataIndexer.java (revision 0) @@ -0,0 +1,61 @@ +/* + * Copyright 2015 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ametys.plugins.odfweb; + +import java.io.IOException; + +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.lucene.document.Document; +import org.xml.sax.SAXException; + +import org.ametys.cms.contenttype.ContentType; +import org.ametys.cms.contenttype.MetadataDefinition; +import org.ametys.cms.contenttype.MetadataSetElement; +import org.ametys.cms.repository.Content; +import org.ametys.odf.contenttype.SubProgramMetadataIndexer; +import org.ametys.plugins.repository.metadata.CompositeMetadata; +import org.ametys.web.renderingcontext.RenderingContext; +import org.ametys.web.renderingcontext.RenderingContextHandler; + +public class WebSubProgramMetadataIndexer extends SubProgramMetadataIndexer +{ + /** Component for getting and setting rendering context */ + protected RenderingContextHandler _renderingContextHandler; + + @Override + public void service(ServiceManager manager) throws ServiceException + { + super.service(manager); + _renderingContextHandler = (RenderingContextHandler) manager.lookup(RenderingContextHandler.ROLE); + } + + @Override + public void indexMetadata(MetadataSetElement metadataSet, CompositeMetadata metadata, String prefix, Content content, ContentType cType, Document document, + MetadataSetElement element, String name, String fieldName, MetadataDefinition definition) throws SAXException, IOException, Exception + { + RenderingContext currentContext = _renderingContextHandler.getRenderingContext(); + try + { + _renderingContextHandler.setRenderingContext(RenderingContext.FRONT); + super.indexMetadata(metadataSet, metadata, prefix, content, cType, document, element, name, fieldName, definition); + } + finally + { + _renderingContextHandler.setRenderingContext(currentContext); + } + } +} Index: main/plugin-odf-web/src/org/ametys/plugins/odfweb/generators/AbstractODFSearchGenerator.java =================================================================== --- main/plugin-odf-web/src/org/ametys/plugins/odfweb/generators/AbstractODFSearchGenerator.java (revision 36748) +++ main/plugin-odf-web/src/org/ametys/plugins/odfweb/generators/AbstractODFSearchGenerator.java (working copy) @@ -252,7 +252,7 @@ } // Title - _addTitleQuery(query, params.get("title"), getBoost("title", serviceId)); + addTitleQuery(query, params.get("title"), getBoost("title", serviceId)); // Catalog String catalog = StringUtils.defaultIfEmpty(params.get("catalog"), parameters.getParameter("catalog", "")); @@ -319,7 +319,7 @@ // Title String title = params.containsKey("title") ? params.get("title").get(0) : null; - _addTitleQuery(query, title, getBoost("title", serviceId)); + addTitleQuery(query, title, getBoost("title", serviceId)); // Catalog String catalog = params.containsKey("catalog") ? params.get("catalog").get(0) : null; @@ -714,7 +714,15 @@ */ protected abstract String getContentType(); - private void _addTitleQuery(BooleanQuery query, String title, float boost) throws ParseException, IllegalArgumentException + /** + * Add title to search query. + * @param query + * @param title + * @param boost + * @throws ParseException + * @throws IllegalArgumentException + */ + protected void addTitleQuery(BooleanQuery query, String title, float boost) throws ParseException, IllegalArgumentException { if (!StringUtils.isEmpty(title)) { Index: main/plugin-odf-web/src/org/ametys/plugins/odfweb/generators/ODFSearch.java =================================================================== --- main/plugin-odf-web/src/org/ametys/plugins/odfweb/generators/ODFSearch.java (revision 36748) +++ main/plugin-odf-web/src/org/ametys/plugins/odfweb/generators/ODFSearch.java (working copy) @@ -15,13 +15,31 @@ */ package org.ametys.plugins.odfweb.generators; +import java.io.IOException; +import java.util.regex.Matcher; + +import org.apache.cocoon.ProcessingException; import org.apache.cocoon.xml.AttributesImpl; import org.apache.cocoon.xml.XMLUtils; +import org.apache.commons.lang.StringUtils; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.MultiFieldQueryParser; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.queryParser.QueryParser.Operator; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.Query; import org.xml.sax.SAXException; - +import org.ametys.cms.lucene.FieldNames; +import org.ametys.odf.contenttype.ODFContentIndexer; +import org.ametys.odf.contenttype.SubProgramMetadataIndexer; import org.ametys.odf.program.ProgramFactory; +import org.ametys.odf.program.SubProgram; +import org.ametys.web.lucene.LuceneConstants; /** @@ -29,6 +47,15 @@ */ public class ODFSearch extends AbstractODFSearchGenerator { + protected boolean _subprogramsSearch; + + @Override + public void generate() throws IOException, SAXException, ProcessingException + { + _subprogramsSearch = parameters.getParameterAsBoolean("subprograms", false); + super.generate(); + } + @Override protected String getContentType() { @@ -36,6 +63,24 @@ } @Override + protected String[] getFields() + { + String[] fields = super.getFields(); + if (_subprogramsSearch) + { + String[] returnFields = new String[fields.length * 2]; + int i = 0; + for (String field : fields) + { + returnFields[i++] = field; + returnFields[i++] = SubProgramMetadataIndexer.INDEX_PREFIX_SUBPROGRAM + field; + } + return returnFields; + } + return fields; + } + + @Override protected void saxAdditionalInfosOnPageHit(Document doc) throws SAXException { Field[] subprograms = doc.getFields("subprograms"); @@ -49,4 +94,29 @@ XMLUtils.createElement(contentHandler, "subprogram", attrs); } } + + @Override + protected void addTitleQuery(BooleanQuery query, String title, float boost) throws ParseException, IllegalArgumentException + { + if (_subprogramsSearch) + { + if (!StringUtils.isEmpty(title)) + { + Matcher m = _TEXTFIELD_PATTERN.matcher(title); + if (!m.matches()) + { + throw new IllegalArgumentException(title + " does not match the expected regular expression : " + _TEXTFIELD_PATTERN.pattern()); + } + + MultiFieldQueryParser parser = new MultiFieldQueryParser(LuceneConstants.LUCENE_VERSION, new String[] {"title", SubProgramMetadataIndexer.INDEX_PREFIX_SUBPROGRAM + "title"}, _analyser); + Query titleQuery = parser.parse(title); + titleQuery.setBoost(boost); + query.add(titleQuery, BooleanClause.Occur.MUST); + } + } + else + { + super.addTitleQuery(query, title, boost); + } + } }