/* 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 com.esri.gpt.framework.search; import java.io.IOException; import java.net.URL; import java.util.AbstractMap; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Properties; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.esri.gpt.catalog.search.SearchGptXslProfile; import com.esri.gpt.framework.search.SearchXslProfile.FORMAT_SEARCH_TO_XSL; import com.esri.gpt.framework.util.ResourcePath; import com.esri.gpt.framework.util.Val; import com.esri.gpt.server.csw.client.CswProfile; import com.esri.gpt.server.csw.client.CswProfiles; /** * The collection of Search Profiles. * * @param <P> the generic type */ public abstract class SearchXslProfiles<P extends SearchXslProfile<?, ?, ?, ?>>{ // class variables ============================================================= /** The LOG. */ private static Logger LOG = Logger.getLogger(SearchXslProfiles.class.getCanonicalName()); // instance variables ========================================================== /** The map. */ private final AbstractMap<String, P> map = new LinkedHashMap<String, P>(); /** The configuration folder path. */ public static final String CONFIG_FOLDER_PATH = "gpt/search/profiles/"; /** The configuration filename. */ private String configurationFileName = "GptXslSearchProfiles.xml"; // constructors ================================================================ /** * Instantiates a new search profiles. * * */ public SearchXslProfiles() { } // properties ================================================================== /** * Gets the configuration file name. * * @return the configuration file name (trimmed, never null) */ public String getConfigurationFileName() { return Val.chkStr(configurationFileName); } /** * Sets the configuration file name. * * @param configurationFileName the new configuration file name */ public void setConfigurationFileName(String configurationFileName) { this.configurationFileName = configurationFileName; } /** * Gets the configuration folder path. * * @return the configuration folder path (trimmed, never null) */ public String getConfigurationFolderPath() { return Val.chkStr(CONFIG_FOLDER_PATH); } // methods ===================================================================== /** * Add a key value pair to profile collection. * Add to profile collection * * @param profile the profile * */ public void addProfile(P profile) { map.put(profile.getId(), profile); } /** * Loads the profile details from configuration file. * * The profiles details are loaded in the collection. Duplicate or invalid * profiles are ignored. * * * @throws ParserConfigurationException * @throws SAXException * @throws ParserConfigurationException * @throws IOException * @throws SAXException * @throws XPathExpressionException */ public abstract void loadProfilefromConfig() throws ParserConfigurationException, SAXException, IOException, XPathExpressionException; /** * Loads the profile details from configuration file. * * The profiles details are loaded in the collection. Duplicate or invalid * profiles are ignored. * * @param filename * @param xslProfileClass Can never be null * @throws ParserConfigurationException * @throws SAXException * @throws ParserConfigurationException * @throws IOException * @throws SAXException * @throws XPathExpressionException */ public void loadProfilefromConfig(String filename, P xslProfileClass, String profileTag) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { if(Val.chkStr(profileTag).equals("")) { profileTag = "Profile"; } String configuration_folder_path = this.getConfigurationFolderPath(); //Create absolute path to xslt files if (configuration_folder_path == null || configuration_folder_path.length() == 0) { // Create absolute path to file Properties properties = new Properties(); final URL url = CswProfiles.class.getResource("CswCommon.properties"); properties.load(url.openStream()); configuration_folder_path = properties .getProperty("DEFAULT_CONFIGURATION_FOLDER_PATH"); } // XML parser load doc specified by filename DocumentBuilder builder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); ResourcePath rscPath = new ResourcePath(); InputSource configFile = rscPath.makeInputSource( configuration_folder_path + filename); if (configFile == null) { configFile = rscPath.makeInputSource( "/" + configuration_folder_path + filename); } Document doc = builder.parse(configFile); // TODO: Move for loop to the super class so that SearchGptXlProfiles // Shares this source too. They are the same in the loop. // Get a list of nodes of which root is Profile tag NodeList profileNodes = doc.getElementsByTagName(profileTag); for (int i = 0; i < profileNodes.getLength(); i++) { // Get "profile" node Node currProfile = profileNodes.item(i); XPath xpath = XPathFactory.newInstance().newXPath(); String id = Val.chkStr(xpath.evaluate("ID", currProfile)); String name = Val.chkStr(xpath.evaluate("Name", currProfile)); String description = Val.chkStr(xpath.evaluate("Description", currProfile)); String requestXslt = Val.chkStr(xpath.evaluate( "GetRecords/XSLTransformations/Request", currProfile)); String expectedGptXmlOutput = Val.chkStr(xpath.evaluate( "GetRecords/XSLTransformations/Request/@expectedGptXmlOutput", currProfile)); if(expectedGptXmlOutput.equals("")) { expectedGptXmlOutput = FORMAT_SEARCH_TO_XSL.MINIMAL_LEGACY_CSWCLIENT.toString(); } String responseXslt = Val.chkStr(xpath.evaluate( "GetRecords/XSLTransformations/Response", currProfile)); String requestKVPs = Val.chkStr(xpath.evaluate("GetRecordByID/RequestKVPs", currProfile)); // GetRecordByID // Xslt to transform the response from GetRecordByID String metadataXslt = Val.chkStr(xpath.evaluate( "GetRecordByID/XSLTransformations/Response", currProfile)); boolean extentSearch = Boolean.parseBoolean(Val.chkStr(xpath.evaluate( "SupportSpatialQuery", currProfile))); boolean liveDataMaps = Boolean.parseBoolean(Val.chkStr(xpath.evaluate( "SupportContentTypeQuery", currProfile))); boolean extentDisplay = Boolean.parseBoolean(Val.chkStr(xpath.evaluate( "SupportSpatialBoundary", currProfile))); boolean harvestable = Boolean.parseBoolean(Val.chkStr(xpath.evaluate( "Harvestable", currProfile))); requestXslt = configuration_folder_path + requestXslt; responseXslt = configuration_folder_path + responseXslt; metadataXslt = configuration_folder_path + metadataXslt; SearchXslProfile profile = null; try { profile = xslProfileClass.getClass().newInstance(); profile.setId(id); profile.setName(name); profile.setDescription(description); profile.setRequestxslt(requestXslt); profile.setResponsexslt(responseXslt); profile.setMetadataxslt(metadataXslt); profile.setSupportsContentTypeQuery(liveDataMaps); profile.setSupportsSpatialBoundary(extentDisplay); profile.setSupportsSpatialQuery(extentSearch); profile.setKvp(requestKVPs); profile.setHarvestable(harvestable); profile.setFormatRequestToXsl( SearchXslProfile.FORMAT_SEARCH_TO_XSL.valueOf(expectedGptXmlOutput)); profile.setFilter_extentsearch(extentSearch); profile.setFilter_livedatamap(liveDataMaps); addProfile((P)profile); } catch (InstantiationException e) { throw new IOException("Could not instantiate profile class" + e.getMessage()); } catch (IllegalAccessException e) { throw new IOException("Could not instantiate profile class" + e.getMessage()); } //CswProfile profile = new CswProfile(id, name, description, requestKVPs, // requestXslt, responseXslt, metadataXslt, liveDataMaps, extentSearch); } } /** * Get csw profile with its id. * * @param id the id * @return the profile by id */ public P getProfileById(String id) { return (P) map.get(id); } /** * Gets the profiles as collection. * * @return the profiles as collection */ public Collection<P> getProfilesAsCollection() { return map.values(); } /** * Gets the size. * * @return the size */ public int getSize() { return map.values().size(); } }