PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/geoportal/src/com/esri/gpt/catalog/search/SearchEngineExternalCsw.java

https://gitlab.com/pachecofgf/geoportal-server
Java | 452 lines | 279 code | 60 blank | 113 comment | 49 complexity | 258c205fb3fc5667e8ac1dd2e9b4a1bc MD5 | raw file
  1. /* See the NOTICE file distributed with
  2. * this work for additional information regarding copyright ownership.
  3. * Esri Inc. licenses this file to You under the Apache License, Version 2.0
  4. * (the "License"); you may not use this file except in compliance with
  5. * the License. You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. package com.esri.gpt.catalog.search;
  16. import java.io.IOException;
  17. import java.io.InputStream;
  18. import java.util.HashMap;
  19. import java.util.Iterator;
  20. import java.util.Map;
  21. import java.util.Map.Entry;
  22. import java.util.logging.Level;
  23. import java.util.logging.Logger;
  24. import javax.xml.transform.TransformerException;
  25. import com.esri.gpt.catalog.harvest.protocols.HarvestProtocolCsw;
  26. import com.esri.gpt.catalog.harvest.repository.HrRecord;
  27. import com.esri.gpt.control.rest.repositories.CswRepository;
  28. import com.esri.gpt.control.webharvest.protocol.Protocol;
  29. import com.esri.gpt.framework.collection.StringSet;
  30. import com.esri.gpt.framework.context.RequestContext;
  31. import com.esri.gpt.framework.util.Val;
  32. import com.esri.gpt.server.csw.client.CswCatalogCapabilities;
  33. import com.esri.gpt.server.csw.client.CswClient;
  34. import com.esri.gpt.server.csw.client.CswProfile;
  35. import com.esri.gpt.server.csw.client.CswRecord;
  36. import com.esri.gpt.server.csw.client.CswRecords;
  37. import com.esri.gpt.server.csw.client.CswSearchRequest;
  38. import com.esri.gpt.server.csw.client.InvalidOperationException;
  39. import com.esri.gpt.server.csw.client.NullReferenceException;
  40. /**
  41. *
  42. * The Class SearchEngineExternalCsw. Request based. For searching
  43. * Harvest Site CSWs in our repositories. Parameters that can be used
  44. * are is "uuid" of harvest site
  45. */
  46. public class SearchEngineExternalCsw
  47. extends SearchEngineCSW {
  48. // class variables =============================================================
  49. /** The class LOG. */
  50. private static final Logger LOG = Logger.getLogger(
  51. SearchEngineExternalCsw.class.getCanonicalName());
  52. // instance variables ==========================================================
  53. /** Tracks The former id we inited on. */
  54. private String formerId = "";
  55. /** The harvest record **/
  56. private HrRecord hrRecord = null;
  57. private boolean hasBeenInited = false;
  58. // constructors ================================================================
  59. /**
  60. *
  61. * Instantiates a new search engine external csw.
  62. */
  63. public SearchEngineExternalCsw(){}
  64. // properties ==================================================================
  65. /**
  66. * Gets the former hint.
  67. *
  68. * @return the former hint
  69. */
  70. public String getFormerId() {
  71. return formerId;
  72. }
  73. /**
  74. * Sets the former hint.
  75. *
  76. * @param formerHint the new former hint
  77. */
  78. public void setFormerId(String formerHint) {
  79. this.formerId = formerHint;
  80. }
  81. /**
  82. * Gets the hr record.
  83. *
  84. * @return the hr record (possibly null)
  85. */
  86. public HrRecord getHrRecord() {
  87. return hrRecord;
  88. }
  89. /**
  90. * Sets the hr record.
  91. *
  92. * @param hrRecord the new hr record
  93. */
  94. public void setHrRecord(HrRecord hrRecord) {
  95. this.hrRecord = hrRecord;
  96. }
  97. // methods =====================================================================
  98. /**
  99. * Tells us if the search is external to GPT9 or Internal
  100. * @return true
  101. */
  102. @Override
  103. protected boolean readIsExternalSearch() {
  104. return true;
  105. }
  106. /**
  107. * Sends a CSW GetRecords request to CSW service.
  108. * @param cswRequest the CSW XML request
  109. * @return the resultant records
  110. * @throws SearchException the search exception
  111. */
  112. @Override
  113. protected CswRecords sendRequest(String cswRequest) throws SearchException {
  114. if(hasBeenInited == false) {
  115. hasBeenInited = true;
  116. init(false);
  117. }
  118. InputStream cswInput = null;
  119. try {
  120. String username = Val.chkStr(this.getCredentials().getUsername());
  121. String password = Val.chkStr(this.getCredentials().getPassword());
  122. if("".equals(username)) {
  123. return super.sendRequest(cswRequest);
  124. }
  125. // submit the request
  126. String url = this.getGetRecordsUrl();
  127. try {
  128. cswInput = this.getCswClient().submitHttpRequest(
  129. "POST", url,cswRequest,username,password);
  130. } catch (Exception e) {
  131. LOG.log(Level.SEVERE, "Exception when Posting CSW query to "+url,e);
  132. if (e instanceof java.net.SocketTimeoutException) {
  133. throw new SearchException("catalog.search.error.searchTimeOut",e,
  134. new String[] {String.valueOf(SearchConfig.getConfiguredInstance()
  135. .getTimeOut()/1000)});
  136. }
  137. throw new SearchException("ERROR while searching authenticating end point " +
  138. url + " : " +e.getMessage()
  139. ,e);
  140. }
  141. // parse the response
  142. try {
  143. return this.parseResponse(this.readInputCharacters(cswInput, "UTF-8"));
  144. } catch (IOException e) {
  145. throw new SearchException("Could not get response for send request", e);
  146. }
  147. } finally {
  148. try {if (cswInput != null) cswInput.close();} catch (Exception ef) {}
  149. }
  150. }
  151. /**
  152. * Marshalls csw records
  153. * @param cswRecords CSW records
  154. * @throws SearchException
  155. */
  156. @Override
  157. protected void marshallRecords(final CswRecords cswRecords)
  158. throws SearchException {
  159. CswProfile profile = this.getCswProfile();
  160. SearchResult result = this.getRequestDefinition().getResult();
  161. //result.setSupportsContentTypeQuery(profile.isSupportsContentTypeQuery());
  162. //result.setSupportsSpatialDisplay(profile.isSupportsSpatialBoundary());
  163. super.marshallRecords(cswRecords);
  164. }
  165. /**
  166. * Gets the metadata as a csw client api record.
  167. *
  168. * @param uuid the uuid
  169. *
  170. * @return the metadata
  171. *
  172. * @throws SearchException the search exception
  173. */
  174. @Override
  175. protected CswRecord getMetadata(String uuid) throws SearchException {
  176. CswRecord record = new CswRecord();
  177. Exception exc = null;
  178. try {
  179. CswProfile profile = getCswProfile();
  180. CswSearchRequest request = new CswSearchRequest();
  181. CswClient client = this.getCswClient();
  182. //client.setReadTimeout(SearchConfig.getConfiguredInstance().getTimeOut());
  183. request.setCswClient(client);
  184. String username = Val.chkStr(this.getCredentials().getUsername());
  185. String password = Val.chkStr(this.getCredentials().getPassword());
  186. if("".equals(username)) {
  187. record = request.getRecordById(this.getGetMetadataRecordUrl(),
  188. uuid, profile);
  189. } else {
  190. record = request.getRecordById(this.getGetMetadataRecordUrl(),
  191. uuid, profile, username, password);
  192. }
  193. } catch (SearchException e) {
  194. exc = e;
  195. } catch (IOException e) {
  196. exc = e;
  197. } catch (TransformerException e) {
  198. exc = e;
  199. } catch (NullReferenceException e) {
  200. exc = e;
  201. } catch (InvalidOperationException e) {
  202. exc = e;
  203. }
  204. if(exc != null) {
  205. throw new
  206. SearchException("Could not get metadata record object uuid=" + uuid + " : "
  207. + exc.getMessage(), exc);
  208. }
  209. return record;
  210. }
  211. /**
  212. * Initialization
  213. *
  214. *@throws SearchException
  215. */
  216. @Override
  217. public void init() throws SearchException {
  218. init(true);
  219. }
  220. /**
  221. * Looks for the id in the repository then fills in
  222. * other information e.g. profile, capabilities url, post url
  223. * @throws SearchException
  224. */
  225. private void init(boolean calledByFactory) throws SearchException {
  226. HrRecord record = this.getHrRecord();
  227. if(record != null && calledByFactory == true) {
  228. if(record.getProtocol() instanceof HarvestProtocolCsw) {
  229. HarvestProtocolCsw hpCsw = (HarvestProtocolCsw) record.getProtocol();
  230. this.setProfileId(hpCsw.getProfile());
  231. }
  232. return;
  233. }
  234. boolean doCapabilities = false;
  235. // get uuid for this search
  236. String uuid = "";
  237. Map<String, String> map = super.getFactoryAttributes();
  238. if(map != null) {
  239. uuid = Val.chkStr(super.getFactoryAttributes().get("uuid"));
  240. }
  241. if("".equals(uuid)) {
  242. uuid = this.getKey();
  243. }
  244. try {
  245. // Extracting getRecordByID and GetRecordsUrl associated with uuid in
  246. // session
  247. RequestContext reqContext = this.getRequestContext();
  248. if(reqContext == null) {
  249. throw new NullPointerException("RequestContext in search engine is null");
  250. }
  251. String sessionKeyPrfx = this.getClass().getCanonicalName() + ":uuid:"
  252. + uuid;
  253. String sessionGetMetadataKey = sessionKeyPrfx + ":GetMetadataRecord:url";
  254. String sessionGetRecordsKey = sessionKeyPrfx + ":GetRecords:url";
  255. String sessionProfileId = sessionKeyPrfx + ":profileId";
  256. String sessionCapabUrl = sessionKeyPrfx + ":capabilities:url";
  257. String sessionCapObject = sessionKeyPrfx + ":capabilities:object";
  258. Object objCapObject = reqContext.extractFromSession(sessionCapObject);
  259. if(objCapObject instanceof CswCatalogCapabilities) {
  260. this.setCapabilities((CswCatalogCapabilities)objCapObject);
  261. }
  262. Object objGetMetadataUrl = reqContext.extractFromSession(
  263. sessionGetMetadataKey);
  264. Object objGetRecordsUrl = reqContext.extractFromSession(
  265. sessionGetRecordsKey);
  266. Object objProfileId = reqContext.extractFromSession(
  267. sessionProfileId);
  268. Object objGetCapabUrl = reqContext.extractFromSession(
  269. sessionCapabUrl);
  270. if (objGetMetadataUrl == null
  271. || "".equals(objGetMetadataUrl.toString().trim())
  272. || objGetRecordsUrl == null
  273. || "".equals(objGetRecordsUrl.toString().trim())
  274. || objProfileId == null
  275. || "".equals(objProfileId.toString().trim())
  276. || objGetCapabUrl == null
  277. || "".equals(objGetCapabUrl.toString().trim())) {
  278. doCapabilities = true;
  279. } else {
  280. this.setGetRecordsUrl(objGetRecordsUrl.toString());
  281. this.setGetMetadataRecordUrl(objGetMetadataUrl.toString());
  282. this.setProfileId(objProfileId.toString());
  283. this.setGetCapabiltiesUrl(objGetCapabUrl.toString());
  284. }
  285. // Checking the db to check if profile and url are still the same
  286. GptRepository repos = new GptRepository();
  287. if(record == null){
  288. record = repos.readHarvestRecord(uuid, this.getRequestContext());
  289. }
  290. Protocol harvestProtocol = record.getProtocol();
  291. if (harvestProtocol instanceof HarvestProtocolCsw) {
  292. HarvestProtocolCsw harvestProtocolCsw =
  293. (HarvestProtocolCsw) harvestProtocol;
  294. if (!this.getProfileId().equals(harvestProtocolCsw.getProfile())
  295. || !this.getGetCapabiltiesUrl().equals(record.getHostUrl())) {
  296. doCapabilities = true;
  297. this.setProfileId(harvestProtocolCsw.getProfile());
  298. this.setGetCapabiltiesUrl(record.getHostUrl());
  299. }
  300. } else {
  301. throw new SearchException("repository id " + uuid + " is not expected"
  302. + " CSW protocol");
  303. }
  304. // Do the capabilities if requested
  305. if (doCapabilities) {
  306. super.init();
  307. // Add info to session
  308. reqContext.addToSession(sessionGetMetadataKey,
  309. this.getGetMetadataRecordUrl());
  310. reqContext.addToSession(sessionGetRecordsKey, this.getGetRecordsUrl());
  311. reqContext.addToSession(sessionCapabUrl, this.getGetCapabiltiesUrl());
  312. reqContext.addToSession(sessionProfileId, this.getProfileId());
  313. reqContext.addToSession(sessionCapObject, this.getCapabilities());
  314. }
  315. } catch (Throwable e) {
  316. throw new SearchException("Error while getting items from repository "
  317. + " with id of " + uuid + e.getMessage(), e);
  318. }
  319. }
  320. /**
  321. * Gets the abstract associated with the key
  322. *
  323. * @return the abstract
  324. * @throws SearchException
  325. */
  326. @Override
  327. public String getKeyAbstract() throws SearchException {
  328. CswCatalogCapabilities cap = this.getCapabilities();
  329. if(cap != null) {
  330. return Val.chkStr(cap.getTitle()) + " : "
  331. + Val.chkStr(cap.getAbstractText());
  332. }
  333. String abs = null;
  334. String uuid = this.getKey();
  335. try {
  336. GptRepository repos = new GptRepository();
  337. HrRecord record = this.getHrRecord();
  338. if(record == null) {
  339. record = repos.readHarvestRecord(uuid, this.getRequestContext());
  340. }
  341. String url = record.getHostUrl();
  342. CswRepository csw = new CswRepository();
  343. if (url.length() > 0) {
  344. abs = csw.transformToHtml(url);
  345. }
  346. } catch (Exception e) {
  347. throw new SearchException("Could not get abstract for uuid =" + uuid, e);
  348. }
  349. return Val.chkStr(abs);
  350. }
  351. /**
  352. * Creates the instances.
  353. *
  354. * @param rids the rids
  355. * @return the array list
  356. * @throws SearchException
  357. * @throws SearchException the search exception
  358. */
  359. @Override
  360. public Map<String, Object> createInstances(StringSet rids) throws SearchException {
  361. Map<String, Object> mRidEngine =
  362. new HashMap<String, Object>();
  363. GptRepository repos = new GptRepository();
  364. Map<String, HrRecord> repositoryRecord =
  365. repos.readHarvestRecords(rids, this.getRequestContext());
  366. // Check if any rids are missing
  367. String msgErr = null;
  368. for(String rid:rids) {
  369. if(repositoryRecord.containsKey(rid)) {
  370. continue;
  371. }
  372. if(msgErr == null) {
  373. msgErr = this.getMessageBroker().retrieveMessage(
  374. "catalog.search.distributedSearch.ridDbEntryNotFound");
  375. }
  376. msgErr = msgErr.replaceAll("\\{0\\}", rid);
  377. mRidEngine.put(rid, msgErr);
  378. }
  379. // Create search engines for existing rids
  380. Iterator<Entry<String, HrRecord>> iter = repositoryRecord.entrySet().iterator();
  381. while(iter.hasNext()) {
  382. Entry<String, HrRecord> entry = iter.next();
  383. String rid = entry.getKey();
  384. HrRecord hrRecord = entry.getValue();
  385. SearchEngineExternalCsw sEngine = new SearchEngineExternalCsw();
  386. sEngine.setKey(rid);
  387. sEngine.setHrRecord(hrRecord);
  388. mRidEngine.put(rid, sEngine);
  389. }
  390. return mRidEngine;
  391. }
  392. }