From 10242eba16228c7fca5d4888c0259e0d0c031590 Mon Sep 17 00:00:00 2001 From: Den Street Date: Tue, 6 Sep 2016 14:10:17 +0300 Subject: [PATCH 1/5] add ContentUtils --- .../controllers/NewSuggestionsController.java | 10 +++- .../app/utils/contents/ContentsUtils.java | 59 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java diff --git a/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java b/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java index 37c78370..fdc748bc 100644 --- a/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java +++ b/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java @@ -1,5 +1,6 @@ package org.ayfaar.app.controllers; +import lombok.extern.slf4j.Slf4j; import one.util.streamex.StreamEx; import org.apache.commons.lang3.tuple.ImmutablePair; import org.ayfaar.app.dao.TermDao; @@ -12,6 +13,7 @@ import org.ayfaar.app.utils.ContentsService; import org.ayfaar.app.utils.TermService; import org.ayfaar.app.utils.UriGenerator; +import org.ayfaar.app.utils.contents.ContentsUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -28,6 +30,7 @@ import static java.util.regex.Pattern.CASE_INSENSITIVE; import static java.util.regex.Pattern.UNICODE_CASE; +@Slf4j @RestController @RequestMapping("api/suggestions") public class NewSuggestionsController { @@ -39,6 +42,7 @@ public class NewSuggestionsController { @Autowired VideoResourceService videoResourceService; @Autowired RecordService recordService; @Autowired ItemService itemService; + @Autowired ContentsUtils contentsUtils; private List escapeChars = Arrays.asList("(", ")", "[", "]", "{", "}"); private static final int MAX_SUGGESTIONS = 5; @@ -74,7 +78,11 @@ public Map suggestions(@RequestParam String q, for (Suggestions item : items) { Queue queriesQueue = getQueue(q); for (Map.Entry suggestion : getSuggestions(queriesQueue, item)) { - allSuggestions.put(suggestion.getKey(), suggestion.getValue()); + if(suggestion.getKey().contains("ии:пункты:")) { + String suggestionParagraph = contentsUtils.filterWordsBeforeAndAfter(suggestion.getValue(), q, 3); + if(suggestionParagraph != null)allSuggestions.put(suggestion.getKey(), suggestion.getKey().substring(10) + ":" + suggestionParagraph); + } + else allSuggestions.put(suggestion.getKey(), suggestion.getValue()); } } return allSuggestions; diff --git a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java new file mode 100644 index 00000000..69fa411b --- /dev/null +++ b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java @@ -0,0 +1,59 @@ +package org.ayfaar.app.utils.contents; + +import org.springframework.stereotype.Component; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Component +public class ContentsUtils { + + public static String filterWordsBeforeAndAfter(String paragraph, String search, int countWordsBeforeAndAfter){ + String wholeFind = ""; + String searchResult = null; + String str = paragraph; + String find = search; + + //check if not the full text + Pattern pattern = Pattern.compile("\\S*" + find + "\\S*",Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); + Matcher matcher = pattern.matcher(str); + while (matcher.find()) { + wholeFind = matcher.group(); + } + + //create minimal string + int countWords = countWordsBeforeAndAfter; + String[] sp = str.split(" +"); // "+" for multiple spaces + List strings = Arrays.asList(sp); + String[] findStringArr = {}; + if (wholeFind.equals("")) findStringArr = find.split(" "); + else findStringArr = wholeFind.split(" "); + + for (int i = 0; i < sp.length; i++) { + if (sp[i].equals(findStringArr[0]) && sp[i + findStringArr.length-1].equals(findStringArr[findStringArr.length-1])) { + + String before = ""; + int iFirst = strings.indexOf(findStringArr[0]); + for (int j = countWords; j > 0; j--) { + if(iFirst-j >= 0) before += sp[iFirst-j]+" "; + } + + String after = ""; + int iLast = strings.indexOf(findStringArr[findStringArr.length-1]); + for (int j = 1; j <= countWords; j++) { + if(iLast+j < sp.length) after += " " + sp[iLast+j]; + } + + before = before.replaceFirst("^[-+.^:,]",""); + after = after.replaceAll("[-+.^:,]$",""); + if(!before.equals(" ") && iFirst - countWords > 0) before = "..." + before; + if(!after.equals(" ") && iLast + countWords < sp.length) after += "..."; + searchResult = before + wholeFind + after; + } + } + + return searchResult; + } +} + From 8a480634af58ca3bd7f83db87071dccd1d303112 Mon Sep 17 00:00:00 2001 From: Den Street Date: Tue, 6 Sep 2016 14:45:38 +0300 Subject: [PATCH 2/5] add fix for 6 words after simple word at search-string start --- src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java index 69fa411b..6813d4d9 100644 --- a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java +++ b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java @@ -39,6 +39,8 @@ public static String filterWordsBeforeAndAfter(String paragraph, String search, if(iFirst-j >= 0) before += sp[iFirst-j]+" "; } + if(before.equals("") && findStringArr.length == 1) countWords *= 2; //Multiple words if "before" empty + String after = ""; int iLast = strings.indexOf(findStringArr[findStringArr.length-1]); for (int j = 1; j <= countWords; j++) { From b7c4271e8aa599f023475b8409c0926aa53c8af2 Mon Sep 17 00:00:00 2001 From: Den Street Date: Tue, 6 Sep 2016 18:35:08 +0300 Subject: [PATCH 3/5] optimize search --- .../app/utils/contents/ContentsUtils.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java index 6813d4d9..6793d38c 100644 --- a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java +++ b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java @@ -30,28 +30,22 @@ public static String filterWordsBeforeAndAfter(String paragraph, String search, if (wholeFind.equals("")) findStringArr = find.split(" "); else findStringArr = wholeFind.split(" "); - for (int i = 0; i < sp.length; i++) { - if (sp[i].equals(findStringArr[0]) && sp[i + findStringArr.length-1].equals(findStringArr[findStringArr.length-1])) { - - String before = ""; - int iFirst = strings.indexOf(findStringArr[0]); - for (int j = countWords; j > 0; j--) { - if(iFirst-j >= 0) before += sp[iFirst-j]+" "; - } + int lengthFindStringArr = findStringArr.length; + String firstPosition = findStringArr[0]; + String lastPosition = findStringArr[lengthFindStringArr - 1]; - if(before.equals("") && findStringArr.length == 1) countWords *= 2; //Multiple words if "before" empty + for (int i = 0; i < sp.length; i++) { + if (sp[i].equals(firstPosition) && sp[i + lengthFindStringArr-1].equals(lastPosition)) { String after = ""; int iLast = strings.indexOf(findStringArr[findStringArr.length-1]); for (int j = 1; j <= countWords; j++) { if(iLast+j < sp.length) after += " " + sp[iLast+j]; } - - before = before.replaceFirst("^[-+.^:,]",""); + after = after.replaceAll("[-+.^:,]$",""); - if(!before.equals(" ") && iFirst - countWords > 0) before = "..." + before; if(!after.equals(" ") && iLast + countWords < sp.length) after += "..."; - searchResult = before + wholeFind + after; + searchResult = wholeFind + after; } } From 2137f2c6f67c110e217c818e44d4ed4df9485006 Mon Sep 17 00:00:00 2001 From: Den Street Date: Tue, 6 Sep 2016 18:49:17 +0300 Subject: [PATCH 4/5] add optimize to search and minimize search paragraph string v.2 --- .../java/org/ayfaar/app/utils/contents/ContentsUtils.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java index 6793d38c..71eb7ddb 100644 --- a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java +++ b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java @@ -33,19 +33,21 @@ public static String filterWordsBeforeAndAfter(String paragraph, String search, int lengthFindStringArr = findStringArr.length; String firstPosition = findStringArr[0]; String lastPosition = findStringArr[lengthFindStringArr - 1]; + int iLast = strings.indexOf(lastPosition); for (int i = 0; i < sp.length; i++) { + String addFirstDots = ""; if (sp[i].equals(firstPosition) && sp[i + lengthFindStringArr-1].equals(lastPosition)) { String after = ""; - int iLast = strings.indexOf(findStringArr[findStringArr.length-1]); for (int j = 1; j <= countWords; j++) { if(iLast+j < sp.length) after += " " + sp[iLast+j]; } - + after = after.replaceAll("[-+.^:,]$",""); if(!after.equals(" ") && iLast + countWords < sp.length) after += "..."; - searchResult = wholeFind + after; + if (!firstPosition.equals(sp[0])) addFirstDots = "..."; + searchResult = addFirstDots + wholeFind + after; } } From 8a01e05f0c0ee92f2e3facc6dba3cae700dc9f44 Mon Sep 17 00:00:00 2001 From: Den Street Date: Wed, 7 Sep 2016 22:48:28 +0300 Subject: [PATCH 5/5] last fix and add test to ContentUtils --- .../controllers/NewSuggestionsController.java | 11 ++- .../app/utils/contents/ContentsUtils.java | 11 +-- .../app/utils/contents/ContentsUtilsTest.java | 88 +++++++++++++++++++ 3 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/ayfaar/app/utils/contents/ContentsUtilsTest.java diff --git a/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java b/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java index fdc748bc..55c41a43 100644 --- a/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java +++ b/src/main/java/org/ayfaar/app/controllers/NewSuggestionsController.java @@ -46,6 +46,7 @@ public class NewSuggestionsController { private List escapeChars = Arrays.asList("(", ")", "[", "]", "{", "}"); private static final int MAX_SUGGESTIONS = 5; + private static final int MAX_WORDS_PARAGRAPH_AFTER_SEARCH = 4; public Map suggestions(String q) { return suggestions(q, false, false, false, false, false, false, false, false, false); @@ -78,11 +79,13 @@ public Map suggestions(@RequestParam String q, for (Suggestions item : items) { Queue queriesQueue = getQueue(q); for (Map.Entry suggestion : getSuggestions(queriesQueue, item)) { - if(suggestion.getKey().contains("ии:пункты:")) { - String suggestionParagraph = contentsUtils.filterWordsBeforeAndAfter(suggestion.getValue(), q, 3); - if(suggestionParagraph != null)allSuggestions.put(suggestion.getKey(), suggestion.getKey().substring(10) + ":" + suggestionParagraph); + String key = suggestion.getKey(); + String value = suggestion.getValue(); + if(key.contains("ии:пункты:")) { + String suggestionParagraph = contentsUtils.filterLengthWordsAfter(value, q, MAX_WORDS_PARAGRAPH_AFTER_SEARCH); + if(suggestionParagraph != "")allSuggestions.put(key, key.substring(10) + ":" + suggestionParagraph); } - else allSuggestions.put(suggestion.getKey(), suggestion.getValue()); + else allSuggestions.put(key, value); } } return allSuggestions; diff --git a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java index 71eb7ddb..c6e72c78 100644 --- a/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java +++ b/src/main/java/org/ayfaar/app/utils/contents/ContentsUtils.java @@ -9,7 +9,7 @@ @Component public class ContentsUtils { - public static String filterWordsBeforeAndAfter(String paragraph, String search, int countWordsBeforeAndAfter){ + public static String filterLengthWordsAfter(String paragraph, String search, int countWordsBeforeAndAfter){ String wholeFind = ""; String searchResult = null; String str = paragraph; @@ -31,27 +31,28 @@ public static String filterWordsBeforeAndAfter(String paragraph, String search, else findStringArr = wholeFind.split(" "); int lengthFindStringArr = findStringArr.length; + int lengthParagraph = sp.length; String firstPosition = findStringArr[0]; String lastPosition = findStringArr[lengthFindStringArr - 1]; int iLast = strings.indexOf(lastPosition); - for (int i = 0; i < sp.length; i++) { + for (int i = 0; i < lengthParagraph; i++) { String addFirstDots = ""; if (sp[i].equals(firstPosition) && sp[i + lengthFindStringArr-1].equals(lastPosition)) { String after = ""; for (int j = 1; j <= countWords; j++) { - if(iLast+j < sp.length) after += " " + sp[iLast+j]; + if(iLast+j < lengthParagraph) after += " " + sp[iLast+j]; } after = after.replaceAll("[-+.^:,]$",""); - if(!after.equals(" ") && iLast + countWords < sp.length) after += "..."; + if(!after.equals(" ") && iLast + countWords < lengthParagraph) after += "..."; if (!firstPosition.equals(sp[0])) addFirstDots = "..."; searchResult = addFirstDots + wholeFind + after; } } - return searchResult; + return searchResult == null ? "" : searchResult; } } diff --git a/src/test/java/org/ayfaar/app/utils/contents/ContentsUtilsTest.java b/src/test/java/org/ayfaar/app/utils/contents/ContentsUtilsTest.java new file mode 100644 index 00000000..7e69f993 --- /dev/null +++ b/src/test/java/org/ayfaar/app/utils/contents/ContentsUtilsTest.java @@ -0,0 +1,88 @@ +package org.ayfaar.app.utils.contents; + + +import org.ayfaar.app.IntegrationTest; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static junit.framework.Assert.assertNull; +import static org.junit.Assert.assertEquals; + +public class ContentsUtilsTest extends IntegrationTest{ + + @Autowired + ContentsUtils contentsUtils; + + @Test //Test full text + public void filterLengthWordsAfterTest(){ + + //ГЛАВА 1 параграф 13.12.1.3 + String paragraph = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа. "; + + String find = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа. "; + String s = contentsUtils.filterLengthWordsAfter(paragraph, find, 3); + + assertEquals("Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа. ", s); + } + + @Test //текст из середины, результат должен быть впереди с "..." и сзади плюс три слова и "..." + public void filterLengthWordsAfterTest1(){ + + + String paragraph = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа. "; + + String find = "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается."; + String s = contentsUtils.filterLengthWordsAfter(paragraph, find, 3); + + assertEquals("...его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет...", s); + } + + @Test //текст с конца строки, троеточие подставляется только впереди строки + public void filterLengthWordsAfterTest2(){ + + + String paragraph = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа."; + + String find = "Умерших личностей нет – есть лишь определенный сценарий-Программа."; + String s = contentsUtils.filterLengthWordsAfter(paragraph, find, 3); + + assertEquals("...Умерших личностей нет – есть лишь определенный сценарий-Программа.", s); + } + + @Test //текст с начала строки, в результат дописывается еще три слова плюс троеточие подставляется только вконце строки + public void filterLengthWordsAfterTest3(){ + + String paragraph = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа."; + + String find = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\","; + String s = contentsUtils.filterLengthWordsAfter(paragraph, find, 3); + + assertEquals("Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", его основой является...", s); + } + + @Test //поиск не существующего текста, должен выдавать пустую строку + public void filterLengthWordsAfterTest4(){ + + String paragraph = "Опыт Формо-системы распространяется и закладывается в \"Память-Мира-о-Былом\", " + + "его основой является Фокусная Динамика УУ-ВВУ. Ничто никуда не девается, не перемещается. " + + "Умерших личностей нет – есть лишь определенный сценарий-Программа."; + + String find = "sdlkdfsfsdfdsdfjs"; + String s = contentsUtils.filterLengthWordsAfter(paragraph, find, 3); + + assertEquals("", s); + } +}