diff --git a/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogApi.java b/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogApi.java index 8ea902ad9c..752b137dc3 100644 --- a/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogApi.java +++ b/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogApi.java @@ -90,7 +90,7 @@ public long post( Map attributes, List attachments, Long m String encoded_Text = new String(attributes.get("Text").getBytes(), StandardCharsets.ISO_8859_1); // charset hell - this seems stupid but works attributes.put("Text", encoded_Text); - String encoded_Subject = new String(attributes.get("Text").getBytes(), StandardCharsets.UTF_8); // charset hell - this seems stupid but works + String encoded_Subject = new String(attributes.get("Subject").getBytes(), StandardCharsets.UTF_8); // charset hell - this seems stupid but works attributes.put("Subject", encoded_Subject); Map new_attributes = new HashMap<>(attributes); @@ -235,19 +235,43 @@ public void delete( Long msgId ) throws LogbookException { * @param search_term * */ - public List search( Map search_term ) throws LogbookException { + public ElogSearchResult search( Map search_term, Integer from, Integer size ) throws LogbookException { Map params = new HashMap<>(); params.put( "mode", "summary" ); - params.put( "reverse", "1" ); - params.put( "npp", 20 ); // number of returned results... + + // Sort by date + if(search_term.containsKey("sort")) { + String sortDirection = search_term.get("sort"); + if("up".equalsIgnoreCase(sortDirection)) { + params.put( "reverse", "0" ); + } else if("down".equalsIgnoreCase(sortDirection)) { + params.put( "reverse", "1" ); + } + search_term.remove("sort"); + } else { + params.put( "reverse", "1" ); + } + + // Pagination parameters + String requestUrl = this.url; + if(from != null && size != null) { + if(size != 0) { + int page = from / size + 1; + requestUrl = String.format("%spage%d", requestUrl, page); + params.put( "npp", size ); + } + } else { + params.put( "npp", 20 ); // number of returned results... + } + params.putAll( search_term ); Map cookies = new HashMap<>(); cookies.put( "unm", this.username ); cookies.put( "upwd", this.password ); - Response resp = Requests.get( this.url ) + Response resp = Requests.get( requestUrl ) .cookies(cookies) .params(params) .followRedirect(false) @@ -257,12 +281,25 @@ public List search( Map search_term ) throws LogbookE validateResponse( resp ); List entries = new ArrayList<>(); + int totalCount = 0; try { TagNode tagNode = new HtmlCleaner().clean( resp.body() ); org.w3c.dom.Document doc = new DomSerializer( new CleanerProperties()).createDOM(tagNode); XPath xpath = XPathFactory.newInstance().newXPath(); NodeList msgIds = (NodeList) xpath.evaluate( "(//tr/td[@class=\"list1\" or @class=\"list2\"][1])/a/@href", doc, XPathConstants.NODESET ); + + // Extract the number of all entries + String expression = "//b[contains(., 'Entries')]"; + String result = (String) xpath.evaluate(expression, doc, XPathConstants.STRING); + if(result != null && !result.isEmpty()) { + java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d+)\\s+Entries"); + java.util.regex.Matcher matcher = pattern.matcher(result); + if(matcher.find()) { + totalCount = Integer.parseInt(matcher.group(1)); + } + } + for( int i = 0; i < msgIds.getLength(); i++ ) { String msgIdStr = msgIds.item(i).getNodeValue(); entries.add( read( Long.valueOf( msgIdStr.substring( msgIdStr.lastIndexOf('/') + 1 ) ))); @@ -271,7 +308,7 @@ public List search( Map search_term ) throws LogbookE throw new LogbookException( "could not parse the elog response", e ); } - return entries; + return ElogSearchResult.of(entries, totalCount); } @@ -504,7 +541,10 @@ private long validateResponse( Response resp ) throws LogbookException { } else { URI loc = URI.create( location ); String[] path = loc.getPath().split("/"); - msgId = Integer.parseInt( path[ path.length-1 ] ); + String msgIdStr = path[ path.length-1 ]; + if(msgIdStr != null && msgIdStr.matches("\\d+")) { + msgId = Integer.parseInt( msgIdStr ); + } } } if( body.contains("form name=form1") || body.contains("type=password") ) { diff --git a/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogClient.java b/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogClient.java index 32d99a4ab7..22c0595146 100644 --- a/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogClient.java +++ b/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogClient.java @@ -271,6 +271,11 @@ public Collection listAttachments(Long logId) { @Override public List findLogs(Map map) { + throw new RuntimeException(new UnsupportedOperationException()); + } + + + public SearchResult findLogsWithPagination(Map map) { Map query = new HashMap<>(map); DateTimeFormatter simple_datetime_formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH); @@ -330,9 +335,30 @@ public List findLogs(Map map) { query.remove("tag"); } + Integer from = null; + Integer size = null; + + if(map.containsKey("from")) { + try { + from = Integer.parseInt(map.get("from")); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + if(map.containsKey("size")) { + try { + size = Integer.parseInt(map.get("size")); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + List entries = new ArrayList<>(); + ElogSearchResult result = null; try { - for( ElogEntry entry : service.search( query ) ) { + result = service.search( query, from, size ); + for( ElogEntry entry : result.getLogs() ) { LogEntryBuilder logBuilder = LogEntryImpl.LogEntryBuilder.log(); logBuilder.id( Long.valueOf( entry.getAttribute("$@MID@$") )); logBuilder.description( entry.getAttribute("Text") ); @@ -372,7 +398,7 @@ public List findLogs(Map map) { } catch(LogbookException e){ e.printStackTrace(); } - return entries; + return SearchResult.of(entries, result.getHitCount()); } @@ -532,7 +558,8 @@ public List findLogsBySearch(String pattern) { List entries = new ArrayList<>(); try{ - for( ElogEntry entry : service.search( query ) ) { + ElogSearchResult result = service.search( query, null, null ); + for( ElogEntry entry : result.getLogs() ) { LogEntryBuilder logBuilder = LogEntryImpl.LogEntryBuilder.log(); logBuilder.id( Long.valueOf( entry.getAttribute("$@MID@$") )); logBuilder.description( entry.getAttribute("Text") ); @@ -583,7 +610,8 @@ public List findLogsByTag(String pattern) { List entries = new ArrayList<>(); try{ - for( ElogEntry entry : service.search( query ) ) { + ElogSearchResult result = service.search( query, null, null ); + for( ElogEntry entry : result.getLogs() ) { LogEntryBuilder logBuilder = LogEntryImpl.LogEntryBuilder.log(); logBuilder.id( Long.valueOf( entry.getAttribute("$@MID@$") )); logBuilder.description( entry.getAttribute("Text") ); @@ -634,7 +662,8 @@ public List findLogsByLogbook(String logbook) { List entries = new ArrayList<>(); try{ - for( ElogEntry entry : service.search( query ) ) { + ElogSearchResult result = service.search( query, null, null ); + for( ElogEntry entry : result.getLogs() ) { LogEntryBuilder logBuilder = LogEntryImpl.LogEntryBuilder.log(); logBuilder.id( Long.valueOf( entry.getAttribute("$@MID@$") )); logBuilder.description( entry.getAttribute("Text") ); @@ -697,5 +726,11 @@ public void delete(Collection logIds) throws LogbookException { } } + + @Override + public SearchResult search(Map map) { + return findLogsWithPagination(map); + } + } diff --git a/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogSearchResult.java b/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogSearchResult.java new file mode 100644 index 0000000000..6eff37c1de --- /dev/null +++ b/app/logbook/elog/src/main/java/org/phoebus/elog/api/ElogSearchResult.java @@ -0,0 +1,34 @@ +package org.phoebus.elog.api; + +import java.util.List; + +public class ElogSearchResult { + + private int hitCount; + private List logs; + + private ElogSearchResult(List logs, int hitCount) { + this.logs = logs; + this.hitCount = hitCount; + } + + public static ElogSearchResult of(List logs, int hits) { + return new ElogSearchResult(logs, hits); + } + + public int getHitCount() { + return hitCount; + } + + public void setHitCount(int hitCount) { + this.hitCount = hitCount; + } + + public List getLogs() { + return logs; + } + + public void setLogs(List logs) { + this.logs = logs; + } +}