List of usage examples for org.apache.commons.lang3 StringUtils countMatches
public static int countMatches(final CharSequence str, final char ch)
Counts how many times the char appears in the given string.
A null or empty ("") String input returns 0 .
StringUtils.countMatches(null, *) = 0 StringUtils.countMatches("", *) = 0 StringUtils.countMatches("abba", 0) = 0 StringUtils.countMatches("abba", 'a') = 2 StringUtils.countMatches("abba", 'b') = 2 StringUtils.countMatches("abba", 'x') = 0
From source file:io.sugo.grok.api.Grok.java
/** * Compile the {@code Grok} pattern to named regex pattern. * // w ww . j a va 2 s .c o m * @param pattern : Grok pattern (ex: %{IP}) * @param namedOnly : Whether to capture named expressions only or not (i.e. %{IP:ip} but not ${IP}) * @throws GrokException runtime expt */ public void compile(String pattern, boolean namedOnly) throws GrokException { if (StringUtils.isBlank(pattern)) { throw new GrokException("{pattern} should not be empty or null"); } namedRegex = pattern; originalGrokPattern = pattern; int index = 0; /** flag for infinite recurtion */ int iterationLeft = 1000; Boolean continueIteration = true; // Replace %{foo} with the regex (mostly groupname regex) // and then compile the regex while (continueIteration) { continueIteration = false; if (iterationLeft <= 0) { throw new GrokException("Deep recursion pattern compilation of " + originalGrokPattern); } iterationLeft--; Matcher m = GrokUtils.GROK_PATTERN.matcher(namedRegex); // Match %{Foo:bar} -> pattern name and subname // Match %{Foo=regex} -> add new regex definition if (m.find()) { continueIteration = true; Map<String, String> group = GrokUtils.namedGroups(m, m.group()); if (group.get("definition") != null) { try { addPattern(group.get("pattern"), group.get("definition")); group.put("name", group.get("name") + "=" + group.get("definition")); } catch (GrokException e) { // Log the exeception } } int count = StringUtils.countMatches(namedRegex, "%{" + group.get("name") + "}"); for (int i = 0; i < count; i++) { String replacement = String.format("(?<name%d>%s)", index, grokPatternDefinition.get(group.get("pattern"))); if (namedOnly && group.get("subname") == null) { replacement = grokPatternDefinition.get(group.get("pattern")); } namedRegexCollection.put("name" + index, (group.get("subname") != null ? group.get("subname") : group.get("name"))); namedRegex = StringUtils.replace(namedRegex, "%{" + group.get("name") + "}", replacement, 1); // System.out.println(_expanded_pattern); index++; } } } if (namedRegex.isEmpty()) { throw new GrokException("Pattern not fount"); } // Compile the regex compiledNamedRegex = Pattern.compile(namedRegex); }
From source file:com.seleniumtests.it.reporter.TestSeleniumTestsReporter2.java
/** * issue #148: Check that when test is retried and retry is OK, summary is correct * @throws Exception// ww w. jav a 2 s.c o m */ @Test(groups = { "it" }) public void testFailsOnlyOnceAndRetriedOk() throws Exception { StubTestClass.failed = false; // execute only the test that fails the first time it's executed executeSubTest(1, new String[] { "com.seleniumtests.it.stubclasses.StubTestClass" }, ParallelMode.METHODS, new String[] { "testWithExceptionOnFirstExec" }); // check content of summary report file String mainReportContent = readSummaryFile(); // only the last execution (ok) is shown Assert.assertEquals(StringUtils.countMatches(mainReportContent, ">testWithExceptionOnFirstExec</a>"), 1); Assert.assertFalse(mainReportContent.contains("<i class=\"fa fa-circle circleSkipped\">")); // check log contain the 2 executions String detailedReportContent1 = readTestMethodResultFile("testWithExceptionOnFirstExec"); Assert.assertTrue(detailedReportContent1.contains("Test is KO with error: some exception")); Assert.assertTrue(detailedReportContent1.contains("Test is OK")); }
From source file:de.micromata.genome.junittools.wicket.WicketTestBuilder.java
@Deprecated public T validateLastRenderedResponseOccurrenceOfString(String searchString, int numberOfOccurrence) { validateEquals(numberOfOccurrence, StringUtils.countMatches(_getLastResponseAsString(), searchString)); return (T) this; }
From source file:com.francetelecom.clara.cloud.scalability.helper.ScalabilityHelper.java
private void logicalModelFactory(ApplicationRelease appRelease, String logicalModelPattern) throws ObjectNotFoundException, InvalidMavenReferenceException { String releaseName = appRelease.getUID(); // CREATE SPRINGOO LOGICAL MODEL LogicalDeployment ld = manageLogicalDeployment .findLogicalDeployment(appRelease.getLogicalDeployment().getId()); int nbGui = StringUtils.countMatches(logicalModelPattern, LETTER_GUI); int nbDB = StringUtils.countMatches(logicalModelPattern, LETTER_DATABASE); int nbStore = StringUtils.countMatches(logicalModelPattern, LETTER_STORE); int nbNode = StringUtils.countMatches(logicalModelPattern, LETTER_NODE); logger.debug("logicalModelFactory {} ", releaseName); Collection<LogicalWebGUIService> guis = new ArrayList<LogicalWebGUIService>(); Collection<LogicalRelationalService> dbs = new ArrayList<LogicalRelationalService>(); Collection<LogicalOnlineStorageService> stores = new ArrayList<LogicalOnlineStorageService>(); Collection<ProcessingNode> nodes = new ArrayList<ProcessingNode>(); for (int g = 0; g < nbGui; g++) { LogicalWebGUIService webGuiService = webGuiServiceFactory(releaseName + String.valueOf(g)); ld.addLogicalService(webGuiService); guis.add(webGuiService);//from ww w . j a va 2 s .c o m } for (int d = 0; d < nbDB; d++) { LogicalRelationalService rdbService = relationalDBServiceFactory(releaseName + String.valueOf(d)); ld.addLogicalService(rdbService); dbs.add(rdbService); } for (int s = 0; s < nbStore; s++) { LogicalOnlineStorageService onlineStorageService = onlineStorageServiceFactory( releaseName + String.valueOf(s)); ld.addLogicalService(onlineStorageService); stores.add(onlineStorageService); } Iterator<LogicalWebGUIService> itGuis = guis.iterator(); for (int n = 0; n < nbNode; n++) { LogicalWebGUIService gui = null; if (itGuis.hasNext()) { gui = itGuis.next(); } ProcessingNode lenService = cfJavaProcessingFactory(ld, releaseName + "Node." + n, gui, dbs, stores); // ld.addExecutionNode(lenService); nodes.add(lenService); } logger.debug("updateLogicalDeployment {}", ld.getName()); long start = System.currentTimeMillis(); try { ld = manageLogicalDeployment.checkOverallConsistencyAndUpdateLogicalDeployment(ld); } catch (BusinessException e) { e.printStackTrace(); // To change body of catch statement use File | // Settings | File Templates. } logger.debug("STATS updateLogicalDeployment duration: " + (System.currentTimeMillis() - start) + "ms"); }
From source file:forge.gui.ImportSourceAnalyzer.java
private void addDefaultPicNames(final PaperCard c, final boolean backFace) { final CardRules card = c.getRules(); final String urls = card.getPictureUrl(backFace); if (StringUtils.isEmpty(urls)) { return;/* w ww .j a v a2s .com*/ } final int numPics = 1 + StringUtils.countMatches(urls, "\\"); if (c.getArtIndex() > numPics) { return; } final String filenameBase = ImageUtil.getImageKey(c, backFace, false); final String filename = filenameBase + ".jpg"; final boolean alreadyHadIt = null != defaultPicNames.put(filename, filename); if (alreadyHadIt) { return; } // Do you shift artIndex by one here? final String newLastSymbol = 0 == c.getArtIndex() ? "" : String.valueOf(c.getArtIndex() /* + 1 */); final String oldFilename = oldCleanString(filenameBase.replaceAll("[0-9]?(\\.full)?$", "")) + newLastSymbol + ".jpg"; //if ( numPics > 1 ) //System.out.printf("Will move %s -> %s%n", oldFilename, filename); defaultPicOldNameToCurrentName.put(oldFilename, filename); }
From source file:io.thekraken.grok.api.Grok.java
/** * Compile the {@code Grok} pattern to named regex pattern. * /*from ww w .j a v a 2 s .co m*/ * @param pattern : Grok pattern (ex: %{IP}) * @param namedOnly : Whether to capture named expressions only or not (i.e. %{IP:ip} but not ${IP}) * @throws GrokException runtime expt */ public void compile(String pattern, boolean namedOnly) throws GrokException { if (StringUtils.isBlank(pattern)) { throw new GrokException("{pattern} should not be empty or null"); } namedRegex = pattern; originalGrokPattern = pattern; int index = 0; /** flag for infinite recurtion */ int iterationLeft = 1000; Boolean continueIteration = true; Matcher cm = GrokUtils.CUSTOM_PATTERN.matcher(namedRegex); while (cm.find()) { Map<String, String> group = GrokUtils.namedGroups(cm, cm.group()); String customPattern = group.get("grok") == null ? group.get("custompattern") : grokPatternDefinition.get(group.get("grokpattern")); String replacement = String.format("(?<name%d>%s)", index, customPattern); namedRegexCollection.put("name" + index, group.get("customname")); namedRegex = StringUtils.replace(namedRegex, group.get("custom"), replacement, 1); index++; } // Replace %{foo} with the regex (mostly groupname regex) // and then compile the regex while (continueIteration) { continueIteration = false; if (iterationLeft <= 0) { throw new GrokException("Deep recursion pattern compilation of " + originalGrokPattern); } iterationLeft--; Matcher m = GrokUtils.GROK_PATTERN.matcher(namedRegex); // Match %{Foo:bar} -> pattern name and subname // Match %{Foo=regex} -> add new regex definition if (m.find()) { continueIteration = true; Map<String, String> group = GrokUtils.namedGroups(m, m.group()); if (group.get("definition") != null) { try { addPattern(group.get("pattern"), group.get("definition")); group.put("name", group.get("name") + "=" + group.get("definition")); } catch (GrokException e) { // Log the exeception } } int count = StringUtils.countMatches(namedRegex, "%{" + group.get("name") + "}"); for (int i = 0; i < count; i++) { String replacement = String.format("(?<name%d>%s)", index, grokPatternDefinition.get(group.get("pattern"))); if (namedOnly && group.get("subname") == null) { replacement = grokPatternDefinition.get(group.get("pattern")); } namedRegexCollection.put("name" + index, (group.get("subname") != null ? group.get("subname") : group.get("name"))); namedRegex = StringUtils.replace(namedRegex, "%{" + group.get("name") + "}", replacement, 1); // System.out.println(_expanded_pattern); index++; } } } if (namedRegex.isEmpty()) { throw new GrokException("Pattern not fount"); } // Compile the regex compiledNamedRegex = Pattern.compile(namedRegex); }
From source file:info.pancancer.arch3.test.TestWorker.java
@Test public void testWorker_endless() throws Exception { byte[] body = setupMessage(); Delivery testDelivery = new Delivery(mockEnvelope, mockProperties, body); setupMockQueue(testDelivery);// ww w . j a va 2 s.c o m Mockito.when(Utilities.parseJSONStr(anyString())).thenCallRealMethod(); Mockito.when(Utilities.parseConfig(anyString())).thenCallRealMethod(); //Because the code that does cleanup in calls resultHandler.waitFor(); we need to actually execute something, even if it does nothing. Mockito.doNothing().when(mockExecutor).execute(any(CommandLine.class), any(DefaultExecuteResultHandler.class)); // This is to mock the cleanup command - we don't really want to execute the command for deleting contents of /datastore, at least not when unit testing on a workstation! PowerMockito.whenNew(DefaultExecutor.class).withNoArguments().thenReturn(mockExecutor); Mockito.when(mockExecHandler.hasResult()).thenReturn(true); PowerMockito.whenNew(DefaultExecuteResultHandler.class).withNoArguments().thenReturn(mockExecHandler); final FutureTask<String> tester = new FutureTask<>(new Callable<String>() { @Override public String call() { LOG.debug("tester thread started"); try { Worker.main(new String[] { "--config", "src/test/resources/workerConfig.ini", "--uuid", "vm123456", "--endless", "--pidFile", "/var/run/arch3_worker.pid" }); } catch (CancellationException | InterruptedException e) { LOG.error("Exception caught: " + e.getMessage()); return e.getMessage(); } catch (Exception e) { e.printStackTrace(); fail("Unexpected exception"); return null; } finally { Mockito.verify(mockAppender, Mockito.atLeastOnce()).doAppend(argCaptor.capture()); String s = appendEventsIntoString(argCaptor.getAllValues()); return s; } } }); final Thread killer = new Thread(new Runnable() { @Override public void run() { LOG.debug("killer thread started"); try { // The endless worker will not end on its own (because it's endless) so we need to wait a little bit (0.5 seconds) and // then kill it as if it were killed by the command-line script (kill_worker_daemon.sh). Thread.sleep(2500); } catch (InterruptedException e) { e.printStackTrace(); LOG.error(e.getMessage()); } tester.cancel(true); } }); ExecutorService es = Executors.newFixedThreadPool(2); es.execute(tester); es.execute(killer); try { tester.get(); } catch (CancellationException e) { Mockito.verify(mockAppender, Mockito.atLeastOnce()).doAppend(argCaptor.capture()); List<LoggingEvent> tmpList = new LinkedList<>(argCaptor.getAllValues()); String output = this.appendEventsIntoString(tmpList); assertTrue(output.contains("The \"--endless\" flag was set, this worker will run endlessly!")); int numJobsPulled = StringUtils.countMatches(output, " WORKER IS PREPARING TO PULL JOB FROM QUEUE "); LOG.info("Number of jobs attempted: " + numJobsPulled); assertTrue("number of jobs attempted > 1", numJobsPulled > 1); } catch (Exception e) { e.printStackTrace(); fail(); } }
From source file:com.seleniumtests.it.reporter.TestReporterControler.java
/** * detailed report should contain only configuration steps corresponding to the test method / test class / test (TestNG test) * By default, test context contains all configuration methods. Check we filter them and we have only one configuration step even if it's retried * (case where test method fails and is retried, \@BeforeMethod is then called several times *///from ww w . java 2 s. co m @Test(groups = { "it" }) public void testReportDetailsOnlyTestConfigurationSteps() throws Exception { executeSubTest(1, new String[] { "com.seleniumtests.it.stubclasses.StubTestClass" }, ParallelMode.METHODS, new String[] { "testAndSubActions", "testInError", "testWithException" }); String detailedReportContent = FileUtils .readFileToString(Paths.get(SeleniumTestsContextManager.getGlobalContext().getOutputDirectory(), "testAndSubActions", "TestReport.html").toFile()); detailedReportContent = detailedReportContent.replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><"); Assert.assertEquals(StringUtils.countMatches(detailedReportContent, "</i></button> Pre test step: set -"), 1); String detailedReportContent2 = FileUtils .readFileToString(Paths.get(SeleniumTestsContextManager.getGlobalContext().getOutputDirectory(), "testInError", "TestReport.html").toFile()); detailedReportContent2 = detailedReportContent2.replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><"); Assert.assertEquals(StringUtils.countMatches(detailedReportContent2, "</i></button> Pre test step: set -"), 1); // check that when test is KO, error cause is displayed Assert.assertTrue(detailedReportContent2.contains("[main] TestLogging: Test is KO with error: error")); String detailedReportContent3 = FileUtils .readFileToString(Paths.get(SeleniumTestsContextManager.getGlobalContext().getOutputDirectory(), "testWithException", "TestReport.html").toFile()); detailedReportContent3 = detailedReportContent3.replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><"); Assert.assertEquals(StringUtils.countMatches(detailedReportContent3, "</i></button> Pre test step: set -"), 1); Assert.assertEquals( StringUtils.countMatches(detailedReportContent3, "</i></button> Post test step: reset -"), 1); // in case of test method error, it is retried so each Before/After method is also replayed. Check it's the last one we have Assert.assertTrue(detailedReportContent3.contains("<div class=\"message-info\">before count: 2</div>")); Assert.assertTrue(detailedReportContent3.contains("<div class=\"message-info\">after count: 3</div>")); }
From source file:com.moviejukebox.tools.StringTools.java
/** * Trim a string to the 'n'th occurrence of a space. * * @param sentanceToTrim/*from ww w.j av a2 s . c o m*/ * @param numOfWords * @return */ public static String getWords(final String sentanceToTrim, int numOfWords) { String returnSentance = sentanceToTrim; // count the number of spaces in the original string int numSpaces = StringUtils.countMatches(sentanceToTrim, " "); LOG.trace("Found {} space(s) in '{}', want {} word(s).", numSpaces, sentanceToTrim, numOfWords); if (numSpaces > 0 && numSpaces >= numOfWords) { // ensure that the number of spaces is no larger than the count if (numSpaces > numOfWords) { LOG.trace("Number of spaces limited to {}", numOfWords); numSpaces = numOfWords; } int pos = -1; for (int i = 1; i <= numSpaces; i++) { pos = sentanceToTrim.indexOf(' ', pos + 1); } returnSentance = sentanceToTrim.substring(0, pos); LOG.trace("Final: '{}'", returnSentance); } return returnSentance; }
From source file:io.bibleget.HTTPCaller.java
/** * * @param myQuery/*from w w w . j ava 2 s . c om*/ * @param selectedVersions * @return * @throws java.lang.ClassNotFoundException * @throws java.io.UnsupportedEncodingException */ public boolean integrityCheck(String myQuery, List<String> selectedVersions) throws ClassNotFoundException, UnsupportedEncodingException { String versionsStr = StringUtils.join(selectedVersions.toArray(), ','); //System.out.println("Starting integrity check on query "+myQuery+" for versions: "+versionsStr); if (indexes == null) { indexes = Indexes.getInstance(); } //build indexes based on versions //final result is true until proved false //set finFlag to false for non-breaking errors, or simply return false for breaking errors boolean finFlag = true; errorMessages.removeAll(errorMessages); List<String> queries = new ArrayList<>(); //if english notation is found, translate to european notation if (myQuery.contains(":") && myQuery.contains(".")) { errorMessages.add(__( "Mixed notations have been detected. Please use either english notation or european notation.")); return false; } else if (myQuery.contains(":")) { if (myQuery.contains(",")) { myQuery = myQuery.replace(",", "."); } myQuery = myQuery.replace(":", ","); } if (myQuery.isEmpty() == false) { if (myQuery.contains(";")) { //System.out.println("We have a semicolon"); queries.addAll(Arrays.asList(myQuery.split(";"))); for (Iterator<String> it = queries.iterator(); it.hasNext();) { if (it.next().isEmpty()) { it.remove(); // NOTE: Iterator's remove method, not ArrayList's, is used. } } } else { //System.out.println("There is no semicolon"); queries.add(myQuery); } } boolean first = true; String currBook = ""; if (queries.isEmpty()) { errorMessages.add(__("You cannot send an empty query.")); return false; } for (String querie : queries) { //System.out.println(querie); querie = toProperCase(querie); //System.out.println(querie); //RULE 1: at least the first query must have a book indicator if (first) { if (querie.matches("^[1-3]{0,1}((\\p{L}\\p{M}*)+)(.*)") == false) { errorMessages.add(MessageFormat.format(__( "The first query <{0}> in the querystring <{1}> must start with a valid book indicator!"), querie, myQuery)); finFlag = false; } first = false; } //RULE 2: for every query that starts with a book indicator, // the book indicator must be followed by valid chapter indicator; // else query must start with valid chapter indicator int bBooksContains; int myidx = -1; String tempBook = ""; if (querie.matches("^[1-3]{0,1}((\\p{L}\\p{M}*)+)(.*)") == true) { //while we're at it, let's capture the book value from the query Pattern pattern = Pattern.compile("^[1-3]{0,1}((\\p{L}\\p{M}*)+)", Pattern.UNICODE_CHARACTER_CLASS); Matcher matcher = pattern.matcher(querie); if (matcher.find()) { tempBook = matcher.group(); bBooksContains = isValidBook(tempBook); myidx = bBooksContains + 1; //if(bBooksContains == false && bBooksAbbrevsContains == false){ if (bBooksContains == -1) { errorMessages.add(MessageFormat.format(__( "The book indicator <{0}> in the query <{1}> is not valid. Please check the documentation for a list of valid book indicators."), tempBook, querie)); finFlag = false; } else { //if(bBooksContains) currBook = tempBook; //querie = querie.replace(tempBook,""); } } Pattern pattern1 = Pattern.compile("^[1-3]{0,1}((\\p{L}\\p{M}*)+)", Pattern.UNICODE_CHARACTER_CLASS); Pattern pattern2 = Pattern.compile("^[1-3]{0,1}((\\p{L}\\p{M}*)+)[1-9][0-9]{0,2}", Pattern.UNICODE_CHARACTER_CLASS); Matcher matcher1 = pattern1.matcher(querie); Matcher matcher2 = pattern2.matcher(querie); int count1 = 0; while (matcher1.find()) { count1++; } int count2 = 0; while (matcher2.find()) { count2++; } if (querie.matches("^[1-3]{0,1}((\\p{L}\\p{M}*)+)[1-9][0-9]{0,2}(.*)") == false || count1 != count2) { errorMessages.add(__("You must have a valid chapter following the book indicator!")); finFlag = false; } querie = querie.replace(tempBook, ""); } else { if (querie.matches("^[1-9][0-9]{0,2}(.*)") == false) { errorMessages.add(__( "A query that doesn't start with a book indicator must however start with a valid chapter indicator!")); finFlag = false; } } //RULE 3: Queries with a dot operator must first have a comma operator; and cannot have more commas than dots if (querie.contains(".")) { Pattern pattern11 = Pattern.compile("[,|\\-|\\.][1-9][0-9]{0,2}\\."); Matcher matcher11 = pattern11.matcher(querie); if (querie.contains(",") == false || matcher11.find() == false) { errorMessages.add(__( "You cannot use a dot without first using a comma or a dash. A dot is a liason between verses, which are separated from the chapter by a comma.")); finFlag = false; } Pattern pattern3 = Pattern.compile("(?<![0-9])(?=(([1-9][0-9]{0,2})\\.([1-9][0-9]{0,2})))"); Matcher matcher3 = pattern3.matcher(querie); int count = 0; while (matcher3.find()) { //RULE 4: verse numbers around dot operators must be sequential if (Integer.parseInt(matcher3.group(2)) >= Integer.parseInt(matcher3.group(3))) { errorMessages.add(MessageFormat.format(__( "Verses concatenated by a dot must be consecutive, instead <{0}> is greater than or equal to <{1}> in the expression <{2}> in the query <{3}>"), matcher3.group(2), matcher3.group(3), matcher3.group(1), querie)); finFlag = false; } count++; } //RULE 5: Dot operators must be preceded and followed by a number from one to three digits, of which the first digit cannot be a 0 if (count == 0 || count != StringUtils.countMatches(querie, ".")) { errorMessages.add(__( "A dot must be preceded and followed by 1 to 3 digits of which the first digit cannot be zero.") + " <" + querie + ">"); finFlag = false; } } //RULE 6: Comma operators must be preceded and followed by a number from one to three digits, of which the first digit cannot be 0 if (querie.contains(",")) { Pattern pattern4 = Pattern.compile("([1-9][0-9]{0,2})\\,[1-9][0-9]{0,2}"); Matcher matcher4 = pattern4.matcher(querie); int count = 0; List<Integer> chapters = new ArrayList<>(); while (matcher4.find()) { //System.out.println("group0="+matcher4.group(0)+", group1="+matcher4.group(1)); chapters.add(Integer.parseInt(matcher4.group(1))); count++; } if (count == 0 || count != StringUtils.countMatches(querie, ",")) { errorMessages.add(__( "A comma must be preceded and followed by 1 to 3 digits of which the first digit cannot be zero.") + " <" + querie + ">" + "(count=" + Integer.toString(count) + ",comma count=" + StringUtils.countMatches(querie, ",") + "); chapters=" + chapters.toString()); finFlag = false; } else { // let's check the validity of the chapter numbers against the version indexes //for each chapter captured in the querystring for (int chapter : chapters) { if (indexes.isValidChapter(chapter, myidx, selectedVersions) == false) { int[] chapterLimit = indexes.getChapterLimit(myidx, selectedVersions); errorMessages.add(MessageFormat.format(__( "A chapter in the query is out of bounds: there is no chapter <{0}> in the book <{1}> in the requested version <{2}>, the last possible chapter is <{3}>"), Integer.toString(chapter), currBook, StringUtils.join(selectedVersions, ","), StringUtils.join(chapterLimit, ','))); finFlag = false; } } } } if (StringUtils.countMatches(querie, ",") > 1) { if (!querie.contains("-")) { errorMessages.add(__("You cannot have more than one comma and not have a dash!")); finFlag = false; } String[] parts = StringUtils.split(querie, "-"); if (parts.length != 2) { errorMessages .add(__("You seem to have a malformed querystring, there should be only one dash.")); finFlag = false; } for (String p : parts) { Integer[] pp = new Integer[2]; String[] tt = StringUtils.split(p, ","); int x = 0; for (String t : tt) { pp[x++] = Integer.parseInt(t); } if (indexes.isValidChapter(pp[0], myidx, selectedVersions) == false) { int[] chapterLimit; chapterLimit = indexes.getChapterLimit(myidx, selectedVersions); // System.out.print("chapterLimit = "); // System.out.println(Arrays.toString(chapterLimit)); errorMessages.add(MessageFormat.format(__( "A chapter in the query is out of bounds: there is no chapter <{0}> in the book <{1}> in the requested version <{2}>, the last possible chapter is <{3}>"), Integer.toString(pp[0]), currBook, StringUtils.join(selectedVersions, ","), StringUtils.join(chapterLimit, ','))); finFlag = false; } else { if (indexes.isValidVerse(pp[1], pp[0], myidx, selectedVersions) == false) { int[] verseLimit = indexes.getVerseLimit(pp[0], myidx, selectedVersions); // System.out.print("verseLimit = "); // System.out.println(Arrays.toString(verseLimit)); errorMessages.add(MessageFormat.format(__( "A verse in the query is out of bounds: there is no verse <{0}> in the book <{1}> at chapter <{2}> in the requested version <{3}>, the last possible verse is <{4}>"), Integer.toString(pp[1]), currBook, Integer.toString(pp[0]), StringUtils.join(selectedVersions, ","), StringUtils.join(verseLimit, ','))); finFlag = false; } } } } else if (StringUtils.countMatches(querie, ",") == 1) { String[] parts = StringUtils.split(querie, ","); //System.out.println(Arrays.toString(parts)); if (indexes.isValidChapter(Integer.parseInt(parts[0]), myidx, selectedVersions) == false) { int[] chapterLimit = indexes.getChapterLimit(myidx, selectedVersions); errorMessages.add(MessageFormat.format(__( "A chapter in the query is out of bounds: there is no chapter <{0}> in the book <{1}> in the requested version <{2}>, the last possible chapter is <{3}>"), parts[0], currBook, StringUtils.join(selectedVersions, ","), StringUtils.join(chapterLimit, ','))); finFlag = false; } else { if (parts[1].contains("-")) { Deque<Integer> highverses = new ArrayDeque<>(); Pattern pattern11 = Pattern.compile("[,\\.][1-9][0-9]{0,2}\\-([1-9][0-9]{0,2})"); Matcher matcher11 = pattern11.matcher(querie); while (matcher11.find()) { highverses.push(Integer.parseInt(matcher11.group(1))); } int highverse = highverses.pop(); if (indexes.isValidVerse(highverse, Integer.parseInt(parts[0]), myidx, selectedVersions) == false) { int[] verseLimit = indexes.getVerseLimit(Integer.parseInt(parts[0]), myidx, selectedVersions); errorMessages.add(MessageFormat.format(__( "A verse in the query is out of bounds: there is no verse <{0}> in the book <{1}> at chapter <{2}> in the requested version <{3}>, the last possible verse is <{4}>"), highverse, currBook, parts[0], StringUtils.join(selectedVersions, ","), StringUtils.join(verseLimit, ','))); finFlag = false; } } else { Pattern pattern12 = Pattern.compile(",([1-9][0-9]{0,2})"); Matcher matcher12 = pattern12.matcher(querie); int highverse = -1; while (matcher12.find()) { highverse = Integer.parseInt(matcher12.group(1)); //System.out.println("[line 376]:highverse="+Integer.toString(highverse)); } if (highverse != -1) { //System.out.println("Checking verse validity for book "+myidx+" chapter "+parts[0]+"..."); if (indexes.isValidVerse(highverse, Integer.parseInt(parts[0]), myidx, selectedVersions) == false) { int[] verseLimit = indexes.getVerseLimit(Integer.parseInt(parts[0]), myidx, selectedVersions); errorMessages.add(MessageFormat.format(__( "A verse in the query is out of bounds: there is no verse <{0}> in the book <{1}> at chapter <{2}> in the requested version <{3}>, the last possible verse is <{4}>"), highverse, currBook, parts[0], StringUtils.join(selectedVersions, ","), StringUtils.join(verseLimit, ','))); finFlag = false; } } } Pattern pattern13 = Pattern.compile("\\.([1-9][0-9]{0,2})$"); Matcher matcher13 = pattern13.matcher(querie); int highverse = -1; while (matcher13.find()) { highverse = Integer.parseInt(matcher13.group(1)); } if (highverse != -1) { if (indexes.isValidVerse(highverse, Integer.parseInt(parts[0]), myidx, selectedVersions) == false) { int[] verseLimit = indexes.getVerseLimit(Integer.parseInt(parts[0]), myidx, selectedVersions); errorMessages.add(MessageFormat.format(__( "A verse in the query is out of bounds: there is no verse <{0}> in the book <{1}> at chapter <{2}> in the requested version <{3}>, the last possible verse is <{4}>"), highverse, currBook, parts[0], StringUtils.join(selectedVersions, ","), StringUtils.join(verseLimit, ','))); finFlag = false; } } } } else { //if there is no comma, it's either a single chapter or an extension of chapters with a dash //System.out.println("no comma found"); String[] parts = StringUtils.split(querie, "-"); //System.out.println(Arrays.toString(parts)); int highchapter = Integer.parseInt(parts[parts.length - 1]); if (indexes.isValidChapter(highchapter, myidx, selectedVersions) == false) { int[] chapterLimit = indexes.getChapterLimit(myidx, selectedVersions); errorMessages.add(MessageFormat.format(__( "A chapter in the query is out of bounds: there is no chapter <{0}> in the book <{1}> in the requested version <{2}>, the last possible chapter is <{3}>"), Integer.toString(highchapter), currBook, StringUtils.join(selectedVersions, ","), StringUtils.join(chapterLimit, ','))); finFlag = false; } } if (querie.contains("-")) { //RULE 7: If there are multiple dashes in a query, there cannot be more dashes than there are dots minus 1 int dashcount = StringUtils.countMatches(querie, "-"); int dotcount = StringUtils.countMatches(querie, "."); if (dashcount > 1) { if (dashcount - 1 > dotcount) { errorMessages.add(__( "There are multiple dashes in the query, but there are not enough dots. There can only be one more dash than dots.") + " <" + querie + ">"); finFlag = false; } } //RULE 8: Dash operators must be preceded and followed by a number from one to three digits, of which the first digit cannot be 0 Pattern pattern5 = Pattern.compile("([1-9][0-9]{0,2}\\-[1-9][0-9]{0,2})"); Matcher matcher5 = pattern5.matcher(querie); int count = 0; while (matcher5.find()) { count++; } if (count == 0 || count != StringUtils.countMatches(querie, "-")) { errorMessages.add(__( "A dash must be preceded and followed by 1 to 3 digits of which the first digit cannot be zero.") + " <" + querie + ">"); finFlag = false; } //RULE 9: If a comma construct follows a dash, there must also be a comma construct preceding the dash Pattern pattern6 = Pattern.compile("\\-([1-9][0-9]{0,2})\\,"); Matcher matcher6 = pattern6.matcher(querie); if (matcher6.find()) { Pattern pattern7 = Pattern.compile("\\,[1-9][0-9]{0,2}\\-"); Matcher matcher7 = pattern7.matcher(querie); if (matcher7.find() == false) { errorMessages.add(__( "If there is a chapter-verse construct following a dash, there must also be a chapter-verse construct preceding the same dash.") + " <" + querie + ">"); finFlag = false; } else { //RULE 10: Chapters before and after dashes must be sequential int chap1 = -1; int chap2 = -1; Pattern pattern8 = Pattern.compile("([1-9][0-9]{0,2})\\,[1-9][0-9]{0,2}\\-"); Matcher matcher8 = pattern8.matcher(querie); if (matcher8.find()) { chap1 = Integer.parseInt(matcher8.group(1)); } Pattern pattern9 = Pattern.compile("\\-([1-9][0-9]{0,2})\\,"); Matcher matcher9 = pattern9.matcher(querie); if (matcher9.find()) { chap2 = Integer.parseInt(matcher9.group(1)); } if (chap1 >= chap2) { errorMessages.add(MessageFormat.format(__( "Chapters must be consecutive. Instead the first chapter indicator <{0}> is greater than or equal to the second chapter indicator <{1}> in the expression <{2}>"), chap1, chap2, querie)); finFlag = false; } } } else { //if there are no comma constructs immediately following the dash //RULE 11: Verses (or chapters if applicable) around each of the dash operator(s) must be sequential Pattern pattern10 = Pattern.compile("([1-9][0-9]{0,2})\\-([1-9][0-9]{0,2})"); Matcher matcher10 = pattern10.matcher(querie); while (matcher10.find()) { int num1 = Integer.parseInt(matcher10.group(1)); int num2 = Integer.parseInt(matcher10.group(2)); if (num1 >= num2) { errorMessages.add(MessageFormat.format(__( "Verses (or chapters if applicable) around the dash operator must be consecutive. Instead <{0}> is greater than or equal to <{1}> in the expression <{2}>"), num1, num2, querie)); finFlag = false; } } } } } return finFlag; }