/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You 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 contains classes pertaining to performing a search on the selected search interface. <h2>Adding a Custom Search Filter to the Search Criteria</h2> An example of how to do this can be found in the GPT help documentation called "Add Custom Search Criteria". The following describes how to add a new Search Filter. It's not the only way. The following describes how to achieve this with or without the source code. <p> Create a new search filter object that either inherits from ISearchFilter, or from one of the SearchFilter* classes. If JSF is being used, the custom filter class can be made into a managed bean so that its properties can be set on the Search JSP page. <p> The new custom filter should then be added to the searchCriteria. <p> <code> Search Criteria searchCriteria = new SearchCriteria(); CustomFilter filter = new CustomFilter(); searchCriteria.getMisselleniousFilters().add(filter); </code> <p> If you are using JSF and you can do the above by adding the custom filter managed bean into the Search Criteria's misselleniousFilters list in the WEB-INF/gpt-faces-config.xml. <p> During Search, your filter will be translated into an xml representation togather with all the other filters. The xsd for this representation can be fould at WEB-INF/class/gpt/search/gptNativeSearch.xsd. This xml is then transformed into a CSW request using the gpt2csw_OGCCore.xslt. Your last step will therefore be to customize the xslt so that your custom search filter parameters can affect the query. <p> <strong>WARNING:</strong> Its important to have all your custom filter classes in the miscellaneous filter list have unique classnames (Object.class.getCanonicalName). If a search criteria is saved, the uniqueness in the names of the classes in the miscellaneous filter list will be important in recreating the new saved search criteria. <strong>NOTE:</strong> In order for your search filter to work, you may have to <p> <UL> <P> <LI> Deprecated - gpt2csw_OGCCore.xslt no longer used. <strike> Edit the gpt2csw_OGCCore.xslt (your XSLT pointed to in gpt.xml/gptConfig/search/@gpt2cswXslt </strike> <P> <LI> New at version 10. Override the method {@link com.esri.gpt.control.georss.RestQueryServlet#parseRequest}. Relates the rest query to the CSW query. <P> <LI> New at version 10. Override the method {@link com.esri.gpt.control.georss.RestQueryServlet#toSearchCriteria} The method relates the custom search filter object to the rest parameters, and adds the custom search filter to a search criteria object. <P> <LI> New at version 10. Replace the query servlet in web.xml with your custom queryServlet. <pre> <servlet> <servlet-name>RestQueryServlet</servlet-name> <servlet-class>com.esri.gpt.control.georss.CustomQueryServlet</servlet-class> <init-param> <param-name>bundleBaseName</param-name> <param-value>gpt.resources.gpt</param-value> </init-param> <load-on-startup>6</load-on-startup> </servlet> </pre> <P> <LI> New at version 10. Edit criteria.jsp specifically javascript function "scReadRestUrlParams" to include your HTML component value into the rest <P> <LI> If your query is to be passed through to other distributed search types you may have to look into the xslts in WEB-INF/class/gpt/profiles to identify which xslts need to be modified e.g. if your query is to be passed to another GPT then .*OGCCORE_ESR_GPT.* xslts will have to be edited. <P> <LI> And/or Add a custom search engine if you want external searches to consult with your custom filter (See topic below on how to do this) </UL> <h2>Adding a Custom Search Engine</h2> Search Engine objects are objects that take in a search criteria object and return an object with search results. Currently there are various CSW search engines implemented. Newly introduced in version 10 is the SearchEngineRest which does not use a CSW kind of workflow. If you would like to implement your custom search engine, you have to :- <P> <UL> <LI>Inherit from the abstract class com.esri.gpt.catalog.search.ASearchEngine or it's existing children. <br/> <b>Note:</b>Version 10: has some new methods. Your class will need to be enhanced to take into account the new methods. <P> <LI> Add an entry into gpt.xml that specifies when your search engine should be invoked so that the SearchEngineFactory automatically picks it up. The entries fall under the xpath /gptConfig/search/repositories. You will need to add a ./repository element with an attribute of \@key and with an \@class attribute. The \@key attribute is a regular expression, and it is a string which the searchFactory matches to an ID so that the searchFactory can pick out the correct Search Engine Object. The \@abstractResourceKey is the abstract shown in the Search In window If you input an \repository\@labelResourcekey attribute, then in the Search External Sites list gui, your search engine will be added as an entry. An example of this is our ArcGIS.com search <repository key="ArcGIS.COM" class="com.esri.gpt.catalog.search.SearchEngineRest" labelResourceKey="catalog.search.searchSite.agsonline" abstractResourceKey="catalog.search.searchSite.agsonline.abstract"> <pa<ameter key="endPointSearchUrl" value="http://www.arcgis.com/sharing/search?q={searchTerms}&start={startIndex}&num={count}&focus={gpt:contenttype?}&f=json"/> <parameter key="defaultParamValues" value="q✔access:shared || access:public || access:private "/> <parameter key="profileId" value="urn:esri:gpt:HTTP:JSON:ESRI:AGSONLINE" /> <parameter key="gpt:contentType" value="liveMap✔maps✕application✔applications"/> </repository> <P> The parameters you put in at \repository\parameters[@key, @value] will be passed on to the search engine of your choice as attributes. These values will be initialized in the search engine as shown in the below sequence diagram. <img src="doc-files/SequenceSearchFactoryInit.jpg"></img> <P> Currently the id of the harvest repository or the key given in the repository item is input into the Search Factory via the search interfaces (HTML, REST ...). The searchFactory will get the host URL from the harvest repository if one exists . This is the URL associated with the id. The Search Factory will then sequentially go down the Search Engine list in the XML file. It will attempt a match the URL with each \@key. first match will be the search engine used for the search. <P> If the URL does not yield any Search Engine Object, then the Search Engine Factory will take the input repository id to match against the \\@key as it did for the id's URL, i.e. The searchFactory will sequentially go down the repository list in the xml file. The first match will be the match that will be used for the search. </UL> <br/> <h4>Search Engine Initialization for Search</h4> <br/> <strong>NOTE:</strong> The Search Factory is fail safe, if a search engine is not found, then the default search engine will be used for a search. If this is the case, the behaviour is logged on the server but the user does not see any error. <h2>Adding a Custom Map Viewer</h2> Inherit from IMapViewer (Read IMapViewer javadoc for more info). Add the class and configurations to gpt.xml mapViewer/instance. There is an example in gpt.xml */ package com.esri.gpt.catalog.search;