Changeset 3957
- Timestamp:
- 29/05/08 12:11:28 (13 years ago)
- Location:
- TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery
- Files:
-
- 3 deleted
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery/DiscoveryServiceSkeleton.java
r3950 r3957 8 8 import java.util.Vector; 9 9 import java.util.logging.Logger; 10 11 import discoveryserviceapi.DoSearchDocument; 10 12 11 13 /** … … 21 23 private static final String[] LIST_NAMES = {"presentFormatList", "orderByFieldList", "scopeList", 22 24 "termTypeList", "spatialOperatorList"}; 25 26 // Constants representing the possible, valid values for the various input list types 27 public static final String FULL_TEXT_TERM_TYPE = "fullText"; 28 public static final String AUTHOR_TERM_TYPE = "author"; 29 public static final String PARAMETER_TERM_TYPE = "parameter"; 30 public static final String OVERLAPS_OPERATOR_TYPE = "overlaps"; 31 public static final String WITHIN_OPERATOR_TYPE = "within"; 32 public static final String NO_OVERLAP_OPERATOR_TYPE = "doesNotOverlap"; 33 23 34 /** 24 35 * Performs the doFullTextSearch operation … … 31 42 { 32 43 logger.info("doSearch() invoked"); 33 discoveryserviceapi.DoSearchReturnDocument response = discoveryserviceapi.DoSearchReturnDocument.Factory.newInstance(); 44 discoveryserviceapi.DoSearchReturnDocument response = 45 discoveryserviceapi.DoSearchReturnDocument.Factory.newInstance(); 34 46 discoveryserviceapi.SearchReturnType responseContent = response.addNewDoSearchReturn(); 35 47 36 // parse the request message37 discoveryserviceapi.SearchType requestContent = request.getDoSearch();38 SearchAgent agent = null;39 40 if ( requestContent.getTermType().equals("fullText") )41 {42 agent = new FullTextSearchAgent( requestContent.getTerm() );43 }44 else if ( requestContent.getTermType().equals("author") )45 {46 agent = new AuthorSearchAgent( requestContent.getTerm() );47 }48 else if ( requestContent.getTermType().equals("parameter") )49 {50 agent = new ParameterSearchAgent( requestContent.getTerm() );51 }52 else53 {54 String errorMessage = "Invalid termType: please use getListNames to get the valid list term types";55 logger.warning(errorMessage);56 throw new UnsupportedOperationException(errorMessage);57 }58 59 if ( requestContent.getTerm().length() > 0 )60 {61 logger.info("Term set - will do term search");62 agent.setDoTerm( true );63 }64 65 if ( requestContent.isSetStart() )66 {67 logger.info("Start position of results set set to: " + requestContent.getStart());68 agent.setStart( requestContent.getStart() );69 }70 71 if ( requestContent.isSetHowMany() )72 {73 logger.info("Result set size set to: " + requestContent.getHowMany());74 agent.setHowMany( requestContent.getHowMany() );75 }76 77 if ( requestContent.isSetOrderBy() )78 {79 logger.info("Results ordered by: " + requestContent.getOrderBy());80 agent.setOrderBy( requestContent.getOrderBy().toString() );81 agent.setDoOrderBy( true );82 if ( requestContent.isSetOrderByDirection() )83 {84 logger.info("Results ordering direction: " + requestContent.getOrderByDirection().toString());85 agent.setOrderByDirection( requestContent.getOrderByDirection().toString() );86 }87 }88 89 if ( requestContent.sizeOfScopeArray() > 0)90 {91 for (int i=0; i<requestContent.sizeOfScopeArray(); i++)92 {93 logger.info("Adding search scope: " + requestContent.getScopeArray(i));94 agent.addNewScope( requestContent.getScopeArray(i).toString() );95 }96 agent.setDoScope( true );97 }98 99 if ( requestContent.isSetBoundingBox() )100 {101 logger.info("Adding bounding box data");102 agent.setLimitWest( requestContent.getBoundingBox().getLimitWest() );103 agent.setLimitSouth( requestContent.getBoundingBox().getLimitSouth() );104 agent.setLimitEast( requestContent.getBoundingBox().getLimitEast() );105 agent.setLimitNorth( requestContent.getBoundingBox().getLimitNorth() );106 agent.setDoSpatio( true );107 if ( requestContent.isSetSpatialOperator() )108 {109 logger.info("Adding spatial operator: " + requestContent.getSpatialOperator());110 agent.setSpatialOperator( requestContent.getSpatialOperator() );111 }112 }113 114 if ( requestContent.isSetDateRange() )115 {116 logger.info("Adding temporal range");117 agent.setDateRangeStart( requestContent.getDateRange().getDateRangeStart() );118 agent.setDateRangeEnd( requestContent.getDateRange().getDateRangeEnd() );119 agent.setDoTemporal( true );120 }121 48 122 49 SearchSummary myResult = null; … … 125 52 try 126 53 { 54 // firstly, parse the request message and set up the search agent 55 logger.info("Preparing search agent for search"); 56 SearchAgent agent = setupSearchAgent(request); 57 127 58 logger.info("Running search..."); 128 59 myResult = agent.doSearch(); … … 186 117 187 118 /** 119 * Prepare the search agent with all the passed in parameters from the WS request, ready to run 120 * a search 121 * 122 * @param request - DoSearchDocument object passed from webservice call 123 * @return SearchAgent object with all required initialisation done for running a search query 124 * @throws DiscoveryWSException if problems encountered whilst doing the set up 125 */ 126 private SearchAgent setupSearchAgent(DoSearchDocument request) throws DiscoveryWSException 127 { 128 discoveryserviceapi.SearchType requestContent = request.getDoSearch(); 129 SearchAgent agent = new SearchAgent(); 130 131 // check if we're doing a term type search - if so, check there is a term to search on 132 if (requestContent.getTermType() != null && requestContent.getTermType().length() > 0) 133 { 134 logger.info("Term type set - checking for term value"); 135 136 if ( requestContent.getTerm().length() > 0 ) 137 { 138 logger.info("Term set - will do term search"); 139 agent.setTermType(requestContent.getTermType()); 140 agent.setTerm(requestContent.getTerm()); 141 } 142 else 143 { 144 logger.info("No term set - ignoring term type search specification"); 145 } 146 } 147 148 if ( requestContent.isSetStart() ) 149 { 150 logger.info("Start position of results set set to: " + requestContent.getStart()); 151 agent.setStart( requestContent.getStart() ); 152 } 153 154 if ( requestContent.isSetHowMany() ) 155 { 156 logger.info("Result set size set to: " + requestContent.getHowMany()); 157 agent.setHowMany( requestContent.getHowMany() ); 158 } 159 160 if ( requestContent.isSetOrderBy() ) 161 { 162 logger.info("Results ordered by: " + requestContent.getOrderBy()); 163 agent.setOrderByField( requestContent.getOrderBy().toString() ); 164 if ( requestContent.isSetOrderByDirection() ) 165 { 166 logger.info("Results ordering direction: " + requestContent.getOrderByDirection().toString()); 167 agent.setOrderByDirection( requestContent.getOrderByDirection().toString() ); 168 } 169 } 170 171 if ( requestContent.sizeOfScopeArray() > 0) 172 { 173 for (int i=0; i<requestContent.sizeOfScopeArray(); i++) 174 { 175 logger.info("Adding search scope: " + requestContent.getScopeArray(i)); 176 agent.addNewScope( requestContent.getScopeArray(i).toString() ); 177 } 178 } 179 180 if ( requestContent.isSetBoundingBox() ) 181 { 182 logger.info("Adding bounding box data"); 183 agent.setLimitWest( requestContent.getBoundingBox().getLimitWest() ); 184 agent.setLimitSouth( requestContent.getBoundingBox().getLimitSouth() ); 185 agent.setLimitEast( requestContent.getBoundingBox().getLimitEast() ); 186 agent.setLimitNorth( requestContent.getBoundingBox().getLimitNorth() ); 187 if ( requestContent.isSetSpatialOperator() ) 188 { 189 logger.info("Adding spatial operator: " + requestContent.getSpatialOperator()); 190 agent.setSpatialOperator( requestContent.getSpatialOperator() ); 191 } 192 } 193 194 if ( requestContent.isSetDateRange() ) 195 { 196 logger.info("Adding temporal range"); 197 agent.setDateRangeStart( requestContent.getDateRange().getDateRangeStart() ); 198 agent.setDateRangeEnd( requestContent.getDateRange().getDateRangeEnd() ); 199 } 200 return agent; 201 } 202 203 204 /** 188 205 * Performs the doPresent operation 189 206 * @param discoveryserviceapi.DoPresentDocument containing search request … … 306 323 else if ( requestContent.getListName().equals("termTypeList") ) 307 324 { 308 list.addListMember( "fullText");309 list.addListMember( "author");310 list.addListMember( "parameter");325 list.addListMember(FULL_TEXT_TERM_TYPE); 326 list.addListMember(AUTHOR_TERM_TYPE); 327 list.addListMember(PARAMETER_TERM_TYPE); 311 328 } 312 329 else if ( requestContent.getListName().equals("spatialOperatorList") ) 313 330 { 314 list.addListMember( "overlaps");315 list.addListMember( "doesNotOverlap");316 list.addListMember( "within");331 list.addListMember(OVERLAPS_OPERATOR_TYPE); 332 list.addListMember(NO_OVERLAP_OPERATOR_TYPE); 333 list.addListMember(WITHIN_OPERATOR_TYPE); 317 334 } 318 335 else -
TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery/InterfaceDBClient.java
r3952 r3957 24 24 * @param sqlQuery 25 25 * @return String[][] - array of results, if applicable, null if none returned 26 * NB, returned array should be populated as follows: String[rowNo][colNo] 26 27 * @throws DiscoveryDBException 27 28 */ -
TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery/PostgresDBClient.java
r3952 r3957 135 135 { 136 136 returnData[i][j] = results.getString(j+1); 137 System.out.println(returnData[i][j]);138 137 } 139 138 i++; 140 139 } 141 140 } 141 logger.info("Query completed and results set retrieved"); 142 142 results.close(); 143 143 } -
TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery/SearchAgent.java
r3952 r3957 9 9 import java.util.Calendar; // needed because xmlbeans uses this for xsd:date 10 10 import java.util.logging.Logger; 11 import java. io.ByteArrayInputStream;11 import java.util.regex.Matcher; 12 12 import java.text.DecimalFormat; 13 13 import java.text.SimpleDateFormat; 14 import javax.xml.namespace.*;15 import javax.xml.xpath.*;16 import org.xml.sax.InputSource;17 import org.w3c.dom.*;18 19 import org.apache.xmlrpc.XmlRpcClient;20 14 21 15 /** … … 24 18 * @author Matt Pritchard <m.j.pritchard@rl.ac.uk> 25 19 */ 26 public abstractclass SearchAgent20 public class SearchAgent 27 21 { 28 22 29 23 private static Logger logger = Logger.getLogger(SearchAgent.class.getName()); 30 24 31 25 private static Properties properties = new ServiceProperties().getProperties(); 32 26 33 27 // Internal defaults 28 29 private String termType = null; 30 34 31 static final BigInteger startDefault = new BigInteger("1"); // default value for first record to display in result set 35 32 static final BigInteger howManyDefault = new BigInteger("30"); // default values for how many results to display in result set 36 boolean doSpatio = false; // flags whether spatial search should be done37 boolean doTemporal = false; // flags whether temporal search should be done38 boolean doTerm = false; // flags whether term search should be done39 boolean doScope = false; // flags whether search should be restricted by scope (dataCentre etc)40 boolean doOrderBy = false; // flags whether ordering should be applied to result set41 33 42 34 // Initialise input parameters, setting values to internal defaults 43 44 BigInteger start = startDefault;45 BigInteger howMany = howManyDefault;46 String term = "";47 String orderByField = ""; // representation used in WSDL e.g. "date", "dataCentre"48 String orderByDirection = "ascending"; //default orderBy direction35 // private int resultId = 0; 36 private BigInteger start = startDefault; 37 private BigInteger howMany = howManyDefault; 38 private String term = ""; 39 private String orderByField = null; // representation used in WSDL e.g. "date", "dataCentre" 40 private String orderByDirection = "ASC"; //default orderBy direction 49 41 // TODO ...add orderByDirection (and to WSDL) 50 42 51 Vector scopes = new Vector();52 String spatialOperator = "overlaps";53 54 BigDecimal limitWest;55 BigDecimal limitSouth;56 BigDecimal limitEast;57 BigDecimal limitNorth;58 Calendar dateRangeStart;59 Calendar dateRangeEnd;43 Vector<String> scopes = new Vector<String>(); 44 private String spatialOperator = "overlaps"; 45 46 private BigDecimal limitWest; 47 private BigDecimal limitSouth; 48 private BigDecimal limitEast; 49 private BigDecimal limitNorth; 50 private Calendar dateRangeStart; 51 private Calendar dateRangeEnd; 60 52 61 53 int hits; 62 Hashtable result = new Hashtable(); 63 54 55 private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 56 57 // info on the DB table structure 58 private final String ORIGINAL_DOCUMENT_TABLE ="ORIGINAL_DOCUMENT"; 59 private final String SPATIAL_DATA_TABLE ="SPATIAL_DATA"; 60 private final String TEMPORAL_DATA_TABLE ="TEMPORAL_DATA"; 61 private final String SPATIAL_TEMPORAL_DATA_TABLE ="SPATIAL_TEMPORAL_DATA"; 62 63 // sql fragments to use when creating sql command 64 private final String WHERE_STATEMENT = " WHERE "; 65 private final String LIMIT_STATEMENT = " LIMIT "; 66 private final String OFFSET_STATEMENT = " OFFSET "; 67 private final String ORDERBY_STATEMENT = " ORDER BY "; 68 64 69 /** 65 70 * Default no-argument constructor. … … 102 107 } 103 108 109 public String getTerm() { return term; } 104 110 105 111 /** … … 107 113 * @param s String, one of "date", "dataCentre", list defined in <code>orderByFieldList</code> returned by <code>getList</code> operation. 108 114 */ 109 public void setOrderBy(String s) 110 { 111 this.orderByField = s; 115 public void setOrderByField(String orderByField) 116 { 117 this.orderByField = orderByField; 118 } 119 120 public String getOrderByField() 121 { 122 return orderByField; 112 123 } 113 124 … … 119 130 public void setOrderByDirection(String s) 120 131 { 121 this.orderByDirection = s; 132 if (s != null && s.equals("descending")) 133 this.orderByDirection = "DESC"; 134 else 135 this.orderByDirection = "ASC"; 136 } 137 138 public String getOrderByDirection() 139 { 140 return orderByDirection; 122 141 } 123 142 … … 136 155 * @return scopes containing String elements like NERC-DDC etc 137 156 */ 138 public Vector getScopes()157 public Vector<String> getScopes() 139 158 { 140 159 return this.scopes; … … 154 173 { 155 174 String scopesStr = ""; 156 Iterator it = this.scopes.iterator();175 Iterator<String> it = this.scopes.iterator(); 157 176 while ( it.hasNext() ) 158 177 { 159 scopesStr += (String) it.next(); 160 } 178 scopesStr += it.next(); 179 } 180 System.out.println("got: " + scopesStr); 181 System.out.println("alternatively: " + this.scopes.toString()); 161 182 return scopesStr; 162 183 } … … 229 250 230 251 /** 231 * Sets whether spatial search should be done.232 * @param b boolean flag true if spatial search is to be done233 */234 public void setDoSpatio(boolean b)235 {236 this.doSpatio = b;237 }238 239 /**240 * Sets whether temporal search should be done.241 * @param b boolean flag true if temporal search is to be done242 */243 public void setDoTemporal(boolean b)244 {245 this.doTemporal = b;246 }247 248 /**249 * Sets whether term search should be done.250 * @param b boolean flag true if term search is to be done251 */252 public void setDoTerm(boolean b)253 {254 this.doTerm = b;255 }256 257 /**258 * Sets whether result set should be ordered.259 * @param b boolean flag true if result set should be ordered260 */261 public void setDoOrderBy(boolean b)262 {263 this.doOrderBy = b;264 }265 266 /**267 * Sets whether scope check should be done.268 * @param b boolean flag true if search should be limited to scope keywords269 */270 public void setDoScope(boolean b)271 {272 this.doScope = b;273 }274 275 /**276 252 * Sets operator used for spatial search 277 * @param s String spatial operator to be applied, must be member of list <code>spatialOperatorsList</code> returned by <code>getList</code> operation. 253 * @param s String spatial operator to be applied, 254 * must be member of list <code>spatialOperatorsList</code> returned by <code>getList</code> operation. 255 * @throws DiscoveryWSException if not correct value of getList list 278 256 */ 279 public void setSpatialOperator(String s) 280 { 257 public void setSpatialOperator(String s) throws DiscoveryWSException 258 { 259 if (s.equals(DiscoveryServiceSkeleton.OVERLAPS_OPERATOR_TYPE) || 260 s.equals(DiscoveryServiceSkeleton.WITHIN_OPERATOR_TYPE) || 261 s.equals(DiscoveryServiceSkeleton.NO_OVERLAP_OPERATOR_TYPE)) 262 { 263 this.spatialOperator = s; 264 } 265 else 266 { 267 String errorMessage = "Invalid spatial operator, " + s + 268 " - please use getListNames to get the valid list of spatial operator types"; 269 logger.warning(errorMessage); 270 throw new DiscoveryWSException(errorMessage); 271 } 281 272 this.spatialOperator = s; 282 273 } … … 291 282 } 292 283 284 public BigDecimal getLimitWest() { return limitWest; } 285 286 public BigDecimal getLimitSouth() { return limitSouth; } 287 288 public BigDecimal getLimitEast() { return limitEast; } 289 290 public BigDecimal getLimitNorth() { return limitNorth; } 291 292 public Calendar getDateRangeStart() { return dateRangeStart; } 293 294 public Calendar getDateRangeEnd() { return dateRangeEnd; } 295 296 public BigInteger getHowMany() { return howMany; } 297 298 public String getTermType() { return termType; } 299 300 public BigInteger getStart() { return start; } 301 302 /** 303 * Set the type of the term to search on; NB, this must be either 'fullText', 'parameter' or 'author' 304 * - if not an exception is thrown 305 * 306 * @param termType 307 */ 308 public void setTermType(String termType) throws DiscoveryWSException 309 { 310 if (termType.equals(DiscoveryServiceSkeleton.FULL_TEXT_TERM_TYPE) || 311 termType.equals(DiscoveryServiceSkeleton.AUTHOR_TERM_TYPE) || 312 termType.equals(DiscoveryServiceSkeleton.PARAMETER_TERM_TYPE)) 313 { 314 this.termType = termType; 315 } 316 else 317 { 318 String errorMessage = "Invalid termType, " + termType + 319 " - please use getListNames to get the valid list of term types"; 320 logger.warning(errorMessage); 321 throw new DiscoveryWSException(errorMessage); 322 } 323 } 324 325 293 326 /** 294 327 * Executes the search and returns a SearchSummary object … … 298 331 { 299 332 300 SearchSummary result = n ew SearchSummary();333 SearchSummary result = null; 301 334 302 335 try … … 307 340 // now run the query using the db client configured appropriately 308 341 InterfaceDBClient client = setupDBClient(); 309 client.runQuery(sqlQuery);342 String[][] results = client.runQuery(sqlQuery); 310 343 311 312 // ByteArrayInputStream resultStream = new ByteArrayInputStream( resultByteArray ); 313 // 314 // // Mark the beginning of the Stream, so can reset before each xpath evaluation (!) 315 // resultStream.mark( resultStream.available() ); 316 // InputSource resultSource = new InputSource( resultStream ); 317 // 318 // XPath xpath = XPathFactory.newInstance().newXPath(); 319 // String hitsExpr = "/exist:result/@hits"; 320 // String documentExpr = "//exist:result/document"; 321 // xpath.setNamespaceContext( new existNamespaceContextImpl() ); 322 // 323 // // If there is a successful search but with no hits, exist sets hitCount=0 rather than hits=0 !! 324 // // Need to check that the thing returned by xpath will convert to an int 325 // try 326 // { 327 // int xpathHits = (new Integer( xpath.evaluate(hitsExpr, resultSource) )).intValue(); 328 // result.setHits( xpathHits ); 329 // } 330 // catch (NumberFormatException e) 331 // { 332 // result.setHits( 0 ); 333 // } 334 // 335 // resultStream.reset(); 336 // NodeList nodeList = (NodeList)xpath.evaluate( documentExpr, resultSource, XPathConstants.NODESET ); 337 // 338 // if ( result.getHits() > 0) 339 // { 340 // Vector documents = new Vector(); 341 // for (int i=0; i<nodeList.getLength(); i++) 342 // { 343 // Hashtable thisDoc = new Hashtable(); 344 // thisDoc.put("name", nodeList.item(i).getFirstChild().getNodeValue() ); 345 // thisDoc.put("matches", 1); 346 // thisDoc.put("position", i); 347 // documents.add( thisDoc ); 348 // } 349 // result.setStatus( true ); 350 // result.setStatusMessage( "Success" ); 351 // result.setDocuments( documents ); 352 // } 353 // else 354 // { 355 // result.setStatus( false ); 356 // result.setStatusMessage("Search was successful but generated no results."); 357 // } 358 // 344 // now extract the results data 345 result = processResults(results); 359 346 360 347 } … … 365 352 } 366 353 354 return result; 355 } 356 357 358 /** 359 * Take the results set returned from a call to doSearch and extract the 360 * data into a SearchSummary object 361 * 362 * @param results - a 2D string array of results from the doSearch call 363 * @return SearchSummary object wrappering the results set 364 */ 365 private SearchSummary processResults(String[][] results) 366 { 367 SearchSummary result = new SearchSummary(); 368 result.setHits(results.length); // NB ensure this is 0 if not data returned 369 370 if ( result.getHits() > 0) 371 { 372 Vector<Hashtable<String, String>> documents = new Vector<Hashtable<String, String>>(); 373 for (int i=0; i < results.length; i++) 374 { 375 Hashtable<String, String> thisDoc = new Hashtable<String, String>(); 376 thisDoc.put("name", results[i][0]); 377 // TODO: these next two are not used anywhere - remove or use? 378 thisDoc.put("matches", String.valueOf(1)); 379 thisDoc.put("position", String.valueOf(i)); 380 documents.add( thisDoc ); 381 } 382 result.setStatus( true ); 383 result.setStatusMessage( "Success" ); 384 result.setDocuments( documents ); 385 } 386 else 387 { 388 result.setStatus( false ); 389 result.setStatusMessage("Search was successful but generated no results."); 390 } 391 367 392 return result; 368 393 } … … 387 412 } 388 413 414 /** 415 * Set up a SQL Select query with the input search parameters 416 * 417 * @return String - SQL command 418 */ 389 419 private String constructSearchQuery() 390 420 { 391 //1. Prepare & execute the search 392 Vector queryParams = new Vector(); 393 394 StringBuffer sqlCmd = new StringBuffer("SELECT original_document_id FROM ORIGINAL DOCUMENT WHERE "); 421 logger.info("Creating search query"); 422 423 // NB, we use the postgres text search function to do term searches 424 StringBuffer fromSqlCmd = new StringBuffer("SELECT original_document_filename FROM " + 425 ORIGINAL_DOCUMENT_TABLE + " "); 426 StringBuffer whereSqlCmd = new StringBuffer(); 427 428 if (this.getTerm() != null && this.getTerm().length() > 0) 429 { 430 logger.info("Adjusting query for " + this.getTermType() + " type search"); 431 432 if (this.getTermType().equals(DiscoveryServiceSkeleton.FULL_TEXT_TERM_TYPE)) 433 { 434 appendWhereClause(whereSqlCmd, " to_tsquery('" + this.term + "') @@ ts_vector "); 435 } 436 else if (this.getTermType().equals(DiscoveryServiceSkeleton.AUTHOR_TERM_TYPE)) 437 { 438 //TODO: IMPLEMENT datamodel side... 439 appendWhereClause(whereSqlCmd, " AUTHOR LIKE %" + this.term + "% "); 440 } 441 else if (this.getTermType().equals(DiscoveryServiceSkeleton.PARAMETER_TERM_TYPE)) 442 { 443 //TODO: IMPLEMENT datamodel side... 444 appendWhereClause(whereSqlCmd, " PARAMETERS LIKE %" + this.term + "% "); 445 } 446 447 } 395 448 396 449 // Substitute values in template xquery string … … 398 451 xqueryStr = xqueryStr.replaceFirst("__subst_scope__", this.getScopesAsString() ); 399 452 400 // orderByField contains $ chars etc so needs special treatment to avoid "java.lang.IllegalArgumentException: Illegal group reference" when replacing 401 String orderByFieldReplace = Matcher.quoteReplacement(this.orderByField); 402 xqueryStr = xqueryStr.replaceAll("__subst_orderByField__", orderByFieldReplace); //NB replaceAll cos more than 1! 403 xqueryStr = xqueryStr.replaceFirst("__subst_orderByDirection__", this.orderByDirection); 404 405 */ // Construct the search clause for spatio temporal search, if necessary 406 String spatialClause = ""; 407 try 408 { 409 SPATIO: 410 if ( 411 doSpatio && 412 limitWest != null && 413 limitSouth != null && 414 limitNorth != null && 415 limitEast != null 416 ) 417 { 418 if ( // Ignore spatial search if search area is global 419 limitWest.intValue() == -180 && 420 limitEast.intValue() == 180 && 421 limitNorth.intValue() == 90 && 422 limitSouth.intValue() == -90 423 ) 424 { 425 doSpatio = false; 426 System.out.println("Global extent selected : spatial search ignored"); 427 break SPATIO; 428 } 429 430 String latFormatPattern = "#0.00"; 431 String lonFormatPattern = "##0.00"; 432 DecimalFormat latFormat = new DecimalFormat( latFormatPattern ); 433 DecimalFormat lonFormat = new DecimalFormat( lonFormatPattern ); 434 435 if ( spatialOperator.equals("within") ) 436 { 437 spatialClause += " sbox_contains_box("; 438 } 439 else if ( spatialOperator.equals("overlaps") ) 440 { 441 spatialClause += " sbox_overlap_box("; 442 } 443 else if ( spatialOperator.equals("doesNotOverlap") ) 444 { 445 spatialClause += " NOT sbox_overlap_box("; 446 } 447 else 448 { 449 doSpatio = false; 450 throw new Exception("Unrecognised spatial operator: " + spatialOperator + " (see spatialOperatorList for supported values)"); 451 } 452 spatialClause += " sbox'("+ 453 lonFormat.format( limitWest.floatValue() )+"d,"+ 454 latFormat.format( limitSouth.floatValue() )+"d),("+ 455 lonFormat.format( limitEast.floatValue() )+"d,"+ 456 latFormat.format( limitNorth.floatValue() )+"d)' "; 457 spatialClause += ", coordinates ) "; 458 459 } 460 else { 461 doSpatio = false; //just in case any components of coordinates were null 462 } 463 } 464 catch (Exception e) 465 { 466 System.out.println("Error converting coordinates to SQL: " + e.toString() ); 467 doSpatio = false; 468 } 469 470 String temporalClause = ""; 471 try 472 { 473 if ( 474 doTemporal && 475 dateRangeStart != null && 476 dateRangeEnd != null && 477 dateRangeEnd.getTimeInMillis() > dateRangeStart.getTimeInMillis() 478 ) 479 { 480 String format = "yyyy-MM-dd"; 481 SimpleDateFormat sdf = new SimpleDateFormat(format); 482 483 temporalClause = " (startdate, enddate) OVERLAPS (DATE '"+sdf.format( dateRangeStart.getTime() )+"', DATE '"+ sdf.format( dateRangeEnd.getTime() ) +"') "; 453 454 */ 455 // Construct the search clause for spatio temporal search, if necessary 456 if (isSpatialSearch()) 457 { 458 logger.info("Adding spatial data to query"); 459 // set up the bounding box geometry for the search 460 String bbox = "SetSRID('BOX3D(" + this.getLimitWest().floatValue() + " " + this.getLimitSouth().floatValue() + 461 ", " + this.getLimitEast().floatValue() + " " + this.getLimitNorth().floatValue() + ")â::box3d,-1)"; 462 463 if (spatialOperator.equals(DiscoveryServiceSkeleton.OVERLAPS_OPERATOR_TYPE)) 464 { 465 appendWhereClause(whereSqlCmd, " geometry && " + bbox + " "); 466 } 467 else if ( spatialOperator.equals(DiscoveryServiceSkeleton.WITHIN_OPERATOR_TYPE) ) 468 { 469 appendWhereClause(whereSqlCmd, " geometry @ " + bbox + " "); 470 } 471 else if ( spatialOperator.equals("doesNotOverlap") ) 472 { 473 appendWhereClause(whereSqlCmd, "NOT geometry && " + bbox + " "); 474 } 475 } 476 477 if (isTemporalSearch()) 478 { 479 logger.info("Adding temporal data to query"); 480 fromSqlCmd.append(", " + TEMPORAL_DATA_TABLE + ", " + SPATIAL_TEMPORAL_DATA_TABLE + ""); 481 appendWhereClause(whereSqlCmd, " " + TEMPORAL_DATA_TABLE + ".start_time, " + 482 TEMPORAL_DATA_TABLE + ".end_time) OVERLAPS (DATE '" + 483 this.sdf.format(this.getDateRangeStart().getTime()) + 484 "', DATE '" + this.sdf.format(this.getDateRangeEnd().getTime() ) + "' AND " + 485 TEMPORAL_DATA_TABLE + ".temporal_data_id == " + 486 SPATIAL_TEMPORAL_DATA_TABLE + ".temporal_data_id"); 487 } 488 489 // if either or both spatial and temporal data is searched on, need to join this with the main 490 // orig doc search query 491 if (isTemporalSearch() || isSpatialSearch()) 492 { 493 whereSqlCmd.append(" AND " + SPATIAL_TEMPORAL_DATA_TABLE + ".original_document_id == " + 494 ORIGINAL_DOCUMENT_TABLE + ".original_document_id"); 495 } 496 497 // add order by, and direction, if required 498 if (this.getOrderByField() != null) 499 { 500 logger.info("Adding ordering info to query"); 501 // orderByField contains $ chars etc so needs special treatment to 502 // avoid "java.lang.IllegalArgumentException: Illegal group reference" when replacing 503 // TODO: is this true now? 504 String orderByFieldReplace = Matcher.quoteReplacement(this.getOrderByField()); 505 whereSqlCmd.append(ORDERBY_STATEMENT + orderByFieldReplace + " " + this.getOrderByDirection()); 506 } 507 508 // lastly, add the size limit and offset of the returned data set 509 logger.info("Adding size limit and offset of results set"); 510 whereSqlCmd.append(OFFSET_STATEMENT + this.getStart()); 511 whereSqlCmd.append(LIMIT_STATEMENT + this.getHowMany()); 512 513 String fullCmd = fromSqlCmd.toString() + WHERE_STATEMENT + whereSqlCmd.toString() + ";"; 514 logger.info("SQL query generated"); 515 logger.fine("Value: " + fullCmd); 516 517 return fullCmd; 518 } 519 520 /** 521 * Append to 'where' clause in sql statement, ensuring 'AND' joins are added where required 522 * 523 * @param whereSqlCmd - StringBuffer holding sql statement 524 * @param clause - string sql clause to add to buffer 525 */ 526 private void appendWhereClause(StringBuffer whereSqlCmd, String clause) 527 { 528 if (whereSqlCmd.length() > 0) 529 whereSqlCmd.append(" AND "); 530 whereSqlCmd.append(clause); 531 } 532 533 /** 534 * Determine whether the search has any temporal data specified 535 * 536 * @return true if includes temporal search, false otherwise 537 * @throws UnsupportedOperationException if 538 */ 539 private boolean isTemporalSearch() throws UnsupportedOperationException 540 { 541 logger.info("Checking if valid temporal data specified"); 542 if (this.getDateRangeStart() != null && this.getDateRangeEnd() != null) 543 { 544 if (dateRangeEnd.getTimeInMillis() > dateRangeStart.getTimeInMillis()) 545 { 546 logger.info("Valid temporal data specified"); 547 return true; 484 548 } 485 549 else 486 550 { 487 doTemporal = false; // just in case any components of date range were null 488 } 489 } 490 catch (Exception e) 491 { 492 System.out.println("Error converting date to SQL: " + e.toString() ); 493 temporalClause = ""; 494 doTemporal = false; 495 } 496 497 String whereClause = ""; 498 if ( doSpatio && doTemporal ) 499 { 500 whereClause = " WHERE " + spatialClause + " AND " + temporalClause + " "; 501 } 502 else if ( doSpatio && !doTemporal ) 503 { 504 whereClause = " WHERE " + spatialClause + " "; 505 } 506 else if ( doTemporal && !doSpatio ) 507 { 508 whereClause = " WHERE " + temporalClause + " "; 509 } 510 else 511 { 512 whereClause = ""; 513 } 514 /* 515 xqueryStr = xqueryStr.replaceFirst("__subst_spatioTempWhereClause__", whereClause ); 516 517 xqueryStr = xqueryStr.replaceFirst("__subst_doTerm__", this.doTerm ? "fn:true()" : "fn:false()"); 518 xqueryStr = xqueryStr.replaceFirst("__subst_doSpatioTemp__", (this.doSpatio | this.doTemporal) ? "fn:true()" : "fn:false()"); 519 xqueryStr = xqueryStr.replaceFirst("__subst_doOrderBy__", this.doOrderBy ? "fn:true()" : "fn:false()"); //NB replaceAll cos more than 1! 520 xqueryStr = xqueryStr.replaceFirst("__subst_doScope__", this.doScope ? "fn:true()" : "fn:false()"); 521 522 //System.out.println("Xquery was \n" + xqueryStr); 523 524 queryParams.addElement( xqueryStr.getBytes("UTF-8") ); 525 */ 526 queryParams.addElement( this.howMany.intValue() ); 527 queryParams.addElement( this.start.intValue() ); 528 //System.out.println("start \n" + this.start.intValue()); 529 //System.out.println("howMany \n" + this.howMany.intValue()); 530 return null; 531 } 532 533 public class existNamespaceContextImpl implements NamespaceContext 534 { 535 public String getNamespaceURI(String prefix) 536 { 537 return "http://exist.sourceforge.net/NS/exist"; 538 } 539 540 // Doesn't matter what the prefix in the source doc is, override it 541 // Important thing is that the namespace URI matches, and that 542 // whatever prefix is set here, is used in the xpath query 543 public String getPrefix(String namespace) 544 { 545 return "exist"; 546 } 547 548 public Iterator getPrefixes(String namespace) 549 { 550 return null; 551 } 552 } 551 String errorMessage = "Invalid temporal data: End date before start date."; 552 logger.warning(errorMessage); 553 throw new UnsupportedOperationException(errorMessage); 554 } 555 } 556 logger.info("No valid temporal data specified"); 557 return false; 558 } 559 560 /** 561 * Determine whether the search has any spatial data specified 562 * NB, checks that global limits aren't specified - if so, this is semantically 563 * equivalent to a non spatial search, so treat as such 564 * 565 * @return true if includes spatial search, false otherwise 566 */ 567 private boolean isSpatialSearch() 568 { 569 logger.info("Checking if valid spatial data specified"); 570 if (this.getLimitEast() != null && this.getLimitWest() != null && 571 this.getLimitNorth() != null && this.getLimitSouth() != null) 572 { 573 if (this.getLimitEast().intValue() != 180 && this.getLimitWest().intValue() != -180 && 574 this.getLimitNorth().intValue() != 90 && this.getLimitSouth().intValue() != -90) 575 { 576 logger.info("Valid spatial data specified"); 577 return true; 578 } 579 logger.info("Spatial data is equivalent to global search - will ignore in search"); 580 } 581 logger.info("No valid spatial data specified"); 582 return false; 583 } 553 584 554 585 … … 658 689 "return <document>{$i}</document> \n"; 659 690 691 692 660 693 } -
TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery/ServiceProperties.java
r3952 r3957 12 12 public ServiceProperties() 13 13 { 14 properties.setProperty("jdbc.uri","jdbc:postgresql://glue.badc.rl.ac.uk /calum:51000");14 properties.setProperty("jdbc.uri","jdbc:postgresql://glue.badc.rl.ac.uk:51000/calum"); 15 15 properties.setProperty("jdbc.username","calum"); 16 16 properties.setProperty("jdbc.password","boybear");
Note: See TracChangeset
for help on using the changeset viewer.