blob: 55bc5ca03e0f43e16e1268c82ed1f7883dd80026 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005-2014 Obeo
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.query.legacy.tools.strings;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.sirius.query.legacy.tools.AcceleoToolsMessages;
import org.eclipse.sirius.query.legacy.tools.AcceleoToolsPlugin;
import org.eclipse.sirius.query.legacy.tools.resources.FileContentMap;
import org.eclipse.sirius.query.legacy.tools.resources.Resources;
/**
* Java language supports pattern matching. This class includes methods for
* examining sequences of characters, for searching strings with or without the
* regular expression library. The public static attribute 'settings' specifies
* the pattern matching configuration for all the methods of this class : <li>
* regular expression</li> <li>ignore case</li> <li>escape characters</li> <li>
* recursive blocks</li>
*
*
*/
public class TextSearch {
/**
* This property is used to disable the blocks recursivity.
*/
public static final String FORCE_NOT_RECURSIVE = "__FORCE_NOT_RECURSIVE__"; //$NON-NLS-1$
/**
* @return the default search
*/
public static TextSearch getDefaultSearch() {
if (TextSearch.defaultSearch == null) {
TextSearch.defaultSearch = new TextSearch(false, false, true);
}
return TextSearch.defaultSearch;
}
private static TextSearch defaultSearch = null;
/**
* @return the regex search
*/
public static TextSearch getRegexSearch() {
if (TextSearch.regexSearch == null) {
TextSearch.regexSearch = new TextSearch(true, false, true);
}
return TextSearch.regexSearch;
}
private static TextSearch regexSearch = null;
/**
* @return the ignore case search
*/
public static TextSearch getIgnoreCaseSearch() {
if (TextSearch.ignoreCaseSearch == null) {
TextSearch.ignoreCaseSearch = new TextSearch(false, true, true);
}
return TextSearch.ignoreCaseSearch;
}
private static TextSearch ignoreCaseSearch = null;
/**
* The sequences of characters are read with (true) or without (false) the
* regular expression library.
*/
private boolean regex;
/**
* Case is ignored if regex is false and IGNORE_CASE_IF_NOT_REGEX is true.
*/
private boolean ignoreCase;
/**
* Blocks are recursively ignored.
* <p>
* Sample :
* <li>"{1 .. [2 .. {3 .. }4 .. ]5 .. }6" is the string to be parsed</li>
* <li>"[","]" and "{","}" are defined blocks</li>
* <li>if RECURSIVE_INHIBS is true then block {1 .. }6 is detected, else
* block {1 .. }4</li>
*/
private boolean recursiveInhibs;
/**
* Constructor.
*
* @param regex
* indicates if the regular expression library is used
* @param ignoreCase
* indicates if the case is ignored
* @param recursiveInhibs
* indicates if the blocks are recursively ignored
*/
private TextSearch(boolean regex, boolean ignoreCase, boolean recursiveInhibs) {
this.regex = regex;
this.ignoreCase = ignoreCase;
this.recursiveInhibs = recursiveInhibs;
}
/**
* Compiles the given regular expression into a pattern.
*
* @param regex
* is the expression to be compiled
* @return a compiled representation of a regular expression
* @throws PatternSyntaxException
* if the expression's syntax is invalid
*/
protected Pattern compile(String regex) {
Pattern pattern = (Pattern) patternMap.get(regex);
if (pattern == null) {
pattern = Pattern.compile(regex);
patternMap.put(regex, pattern);
}
return pattern;
}
private Map patternMap = new HashMap();
/**
* Indicates if the strings are matching.
* <p>
* The pattern matching configuration (Strings.settings) has to be verified
* before.
*
* @param s1
* is the first string
* @param s2
* is the second string
* @return true if the strings are matching
*/
public boolean matches(String s1, String s2) {
if (s1 == null && s2 == null) {
return true;
}
if (s1 == null || s2 == null) {
return false;
}
if (regex) {
Pattern pattern = compile(s2);
Matcher m = pattern.matcher(s1);
return m.matches();
} else {
if (ignoreCase) {
return s1.equalsIgnoreCase(s2);
} else {
return s1.equals(s2);
}
}
}
/**
* Returns the index within the buffer of the first occurrence of the
* specified substring.
* <p>
* The pattern matching configuration (Strings.settings) has to be verified
* before.
*
* @param buffer
* is the text to be explored
* @param tag
* is the substring to search for
* @return The index within the buffer of the first occurrence of the
* specified substring. If it does not occur as a substring,
* Int2(-1,-1) is returned.
*/
public Int2 indexOf(final String buffer, final String tag) {
return indexOf(buffer, tag, 0);
}
/**
* Returns the index within the buffer of the first occurrence of the
* specified substring, starting at the specified index. If no such
* substring occurs in this string at or after position pos, then
* Int2(-1,-1) is returned.
* <p>
* The pattern matching configuration (Strings.settings) has to be verified
* before.
*
* @param buffer
* is the text to be explored
* @param tag
* is the substring to search for
* @param pos
* is the index to start the search from
* @return The index within the buffer of the first occurrence of the
* specified substring, starting at the specified index. If it does
* not occur as a substring, or pos < 0, or buffer.length() <= pos,
* Int2(-1,-1) is returned.
*/
public Int2 indexOf(final String buffer, final String tag, int pos) {
return indexIn(buffer, tag, pos, buffer.length());
}
/**
* Returns the index within the buffer of the first occurrence of the
* specified substring. If no such substring occurs in this string, then
* Int2(-1,-1) is returned.
*
* @param buffer
* is the text to be explored
* @param tag
* is the substring to search for
* @param spec
* is the pattern's escape character
* @param inhibs
* are the ignored sub-blocks
* @return the index within the buffer of the first occurrence of the
* specified substring. If it does not occur as a substring,
* Int2(-1,-1) is returned. It returns 0 if (tag.length() == 0).
*/
public Int2 indexOf(final String buffer, final String tag, String spec, String[][] inhibs) {
return indexOf(buffer, tag, 0, spec, inhibs);
}
/**
* Returns the index within the buffer of the first occurrence of the
* specified substring, starting at the specified index. If no such
* substring occurs in this string at or after position pos, then
* Int2(-1,-1) is returned.
* <p>
* An inhibs element sample : String[] = { 1,2 (,3)? }
* <li>1:begin tag "</li>
* <li>2:end tag "</li>
* <li>3:blocks properties FORCE_NOT_RECURSIVE</li>
*
* @param buffer
* is the text to be explored
* @param tag
* is the substring to search for
* @param pos
* is the beginning index
* @param spec
* is the pattern's escape character
* @param inhibs
* are the ignored sub-blocks
* @return the index within the buffer of the first occurrence of the
* specified substring, starting at the specified index. If it does
* not occur as a substring, or pos < 0, or buffer.length() <= pos,
* Int2(-1,-1) is returned. It returns 0 if (tag.length() == 0).
*/
public Int2 indexOf(final String buffer, final String tag, int pos, String spec, String[][] inhibs) {
return indexOf(buffer, tag, pos, spec, null, inhibs);
}
/**
* Returns the index within the buffer of the first occurrence of the
* specified substring, starting at the specified index. If no such
* substring occurs in this string at or after position pos, then
* Int2(-1,-1) is returned.
* <p>
* An inhibs element sample : String[] = { 1,2 (,3)? }
* <li>1:begin tag "</li>
* <li>2:end tag "</li>
* <li>3:blocks properties FORCE_NOT_RECURSIVE</li>
*
* @param buffer
* is the text to be explored
* @param tag
* is the substring to search for
* @param pos
* is the beginning index
* @param spec
* is the pattern's escape character
* @param jump
* is a scanner that ignores a sequence of characters
* @param inhibs
* are the ignored sub-blocks
* @return the index within the buffer of the first occurrence of the
* specified substring, starting at the specified index. If it does
* not occur as a substring, or pos < 0, or buffer.length() <= pos,
* Int2(-1,-1) is returned. It returns 0 if (tag.length() == 0).
*/
public Int2 indexOf(final String buffer, final String tag, int pos, String spec, Jump jump, String[][] inhibs) {
return indexIn(buffer, tag, pos, buffer.length(), spec, jump, inhibs);
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || posEnd >
* buffer.length()) => -1
*/
public Int2 indexIn(final String buffer, final String tag, int posBegin, int posEnd) {
if (buffer == null || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return Int2.NOT_FOUND;
}
if (tag == null || tag.length() == 0) {
return Int2.NOT_FOUND;
}
String substring = buffer.substring(posBegin, posEnd);
if (regex) {
Pattern pattern = compile(tag);
Matcher m = pattern.matcher(substring);
if (m.find()) {
return new Int2(posBegin + m.start(), posBegin + m.end());
} else {
return Int2.NOT_FOUND;
}
} else {
int i;
if (ignoreCase) {
i = substring.toLowerCase().indexOf(tag.toLowerCase());
} else {
i = substring.indexOf(tag);
}
if (i > -1) {
int b = posBegin + i;
return new Int2(b, b + tag.length());
} else {
return Int2.NOT_FOUND;
}
}
}
public Int2 indexIn(final String buffer, final String tag, int posBegin, int posEnd, String spec, String[][] inhibs) {
return indexIn(buffer, tag, posBegin, posEnd, spec, null, inhibs);
}
public Int2 indexIn(final String buffer, final String tag, int posBegin, int posEnd, String spec, Jump jump, String[][] inhibs) {
if (buffer == null || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return Int2.NOT_FOUND;
}
if (spec == null && inhibs == null) {
return indexIn(buffer, tag, posBegin, posEnd);
}
if (tag == null) {
return Int2.NOT_FOUND;
}
int inhibs_size = 0;
if (inhibs != null) {
inhibs_size = inhibs.length;
}
Int2[] positions = new Int2[3 + inhibs_size];
for (int i = 0; i < positions.length; i++) {
positions[i] = new Int2(-2, -2);
}
while (posBegin > -1 && posBegin < posEnd) {
// Positions for tags and inhibs
if (positions[0].b() != -1 && spec != null && posBegin > positions[0].b()) {
positions[0] = indexIn(buffer, spec, posBegin, posEnd); // spec
}
if (positions[1].b() != -1 && posBegin > positions[1].b()) {
positions[1] = indexIn(buffer, tag, posBegin, posEnd); // tag
}
if (positions[2].b() != -1 && jump != null && posBegin > positions[2].b()) {
positions[2] = jump.begin(buffer, posBegin, posEnd); // jump
}
for (int i = 3; i < positions.length; i++) { // inhibsTag
if (positions[i].b() != -1 && posBegin > positions[i].b()) {
positions[i] = indexIn(buffer, inhibs[i - 3][0], posBegin, posEnd);
}
}
// Get next position
int positionMin = posEnd;
int iPositionMin = -1;
for (int i = 0; i < positions.length; i++) {
if ((positions[i].b() > -1) && (positions[i].b() < positionMin)) {
iPositionMin = i;
positionMin = positions[i].b();
}
}
if (iPositionMin == -1 /* NOT FOUND */) {
return Int2.NOT_FOUND;
}
// Get the next element
if (iPositionMin == 0 /* spec */) {
posBegin = positions[iPositionMin].e();
} else if (iPositionMin == 1 /* tag */) {
return positions[iPositionMin];
} else if (iPositionMin == 2 /* jump */) {
posBegin = jump.end(buffer, positions[iPositionMin], posEnd, spec, inhibs);
} else if (iPositionMin >= 3 /* inhibsTag */) {
boolean forceNotRecursive;
if (inhibs[iPositionMin - 3].length >= 3 && inhibs[iPositionMin - 3][2] != null) {
forceNotRecursive = inhibs[iPositionMin - 3][2].indexOf(TextSearch.FORCE_NOT_RECURSIVE) > -1;
} else {
forceNotRecursive = false;
}
posBegin = blockIndexEndIn(buffer, inhibs[iPositionMin - 3][0], inhibs[iPositionMin - 3][1], positions[iPositionMin].b(), posEnd,
(recursiveInhibs && !forceNotRecursive) ? true : false, spec, jump, (recursiveInhibs && !forceNotRecursive) ? inhibs : null).e();
}
};
return Int2.NOT_FOUND;
}
/*
* (endTag.length()==0) => buffer.length() (endTag not found || posBegin ne
* correspond pas a beginTag) => -1 (posBegin < 0 ||
* (buffer.length()-posBegin) <= 0) => -1
*/
public Int2 blockIndexEndOf(final String buffer, String beginTag, String endTag, int posBegin, boolean recursive) {
return blockIndexEndOf(buffer, beginTag, endTag, posBegin, recursive, null, null);
}
public Int2 blockIndexEndOf(final String buffer, String beginTag, String endTag, int posBegin, boolean recursive, String spec, String[][] inhibs) {
return blockIndexEndOf(buffer, beginTag, endTag, posBegin, recursive, spec, null, inhibs);
}
public Int2 blockIndexEndOf(final String buffer, String beginTag, String endTag, int posBegin, boolean recursive, String spec, Jump jump, String[][] inhibs) {
return blockIndexEndIn(buffer, beginTag, endTag, posBegin, buffer.length(), recursive, spec, jump, inhibs);
}
/*
* (endTag.length()==0) => buffer.length() (endTag not found || posBegin ne
* correspond pas a beginTag) => -1 (posBegin < 0 || posEnd < 0 || posEnd <=
* posBegin || posEnd > buffer.length()) => -1
*/
public Int2 blockIndexEndIn(final String buffer, String beginTag, String endTag, int posBegin, int posEnd, boolean recursive) {
return blockIndexEndIn(buffer, beginTag, endTag, posBegin, posEnd, recursive, null, null);
}
public Int2 blockIndexEndIn(final String buffer, String beginTag, String endTag, int posBegin, int posEnd, boolean recursive, String spec, String[][] inhibs) {
return blockIndexEndIn(buffer, beginTag, endTag, posBegin, posEnd, recursive, spec, null, inhibs);
}
public Int2 blockIndexEndIn(final String buffer, String beginTag, String endTag, int posBegin, int posEnd, boolean recursive, String spec, Jump jump, String[][] inhibs) {
if (buffer == null || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return Int2.NOT_FOUND;
}
// Error cases
if (beginTag == null) {
return Int2.NOT_FOUND;
}
if (endTag == null) {
return Int2.NOT_FOUND;
}
Int2 posBeginInt2 = indexIn(buffer, beginTag, posBegin, posEnd);
if (beginTag.length() == 0) {
recursive = false;
} else if (posBeginInt2.b() != posBegin) {
return Int2.NOT_FOUND;
}
if (endTag.length() == 0) {
return new Int2(posEnd, posEnd);
}
// Block search
int nbBeginTagOuvert = 1;
int pos = posBeginInt2.e();
int inhibs_size = 0;
if (inhibs != null) {
inhibs_size = inhibs.length;
}
Int2[] positions = new Int2[4 + inhibs_size];
for (int i = 0; i < positions.length; i++) {
positions[i] = new Int2(-2, -2);
}
while (pos > -1 && pos < posEnd) {
// Positions for end, begin, and inhibs
if (positions[0].b() != -1 && spec != null && pos > positions[0].b()) {
positions[0] = indexIn(buffer, spec, pos, posEnd); // spec
}
if (positions[1].b() != -1 && pos > positions[1].b()) {
positions[1] = indexIn(buffer, endTag, pos, posEnd); // endTag
}
if (positions[2].b() != -1 && recursive && pos > positions[2].b()) {
positions[2] = indexIn(buffer, beginTag, pos, posEnd); // beginTag
}
if (positions[3].b() != -1 && jump != null && pos > positions[3].b()) {
positions[3] = jump.begin(buffer, pos, posEnd); // jump
}
for (int i = 4; i < positions.length; i++) { // inhibsTag
if (positions[i].b() != -1 && pos > positions[i].b()) {
positions[i] = indexIn(buffer, inhibs[i - 4][0], pos, posEnd);
}
}
// Get next position
int positionMin = posEnd;
int iPositionMin = -1;
for (int i = 0; i < positions.length; i++) {
if ((positions[i].b() > -1) && (positions[i].b() < positionMin)) {
iPositionMin = i;
positionMin = positions[i].b();
}
}
if (iPositionMin == -1 /* NOT FOUND */) {
return Int2.NOT_FOUND;
}
// Get the next element
if (iPositionMin == 0 /* spec */) {
pos = positions[iPositionMin].e();
} else if (iPositionMin == 1 /* endTag */) {
nbBeginTagOuvert--;
pos = positions[iPositionMin].e();
if (!recursive) {
return positions[iPositionMin];
}
} else if (iPositionMin == 2 /* beginTag */) {
nbBeginTagOuvert++;
pos = positions[iPositionMin].e();
} else if (iPositionMin == 3 /* jump */) {
pos = jump.end(buffer, positions[iPositionMin], posEnd, spec, inhibs);
} else if (iPositionMin >= 4 /* inhibsTag */) {
boolean forceNotRecursive;
if (inhibs[iPositionMin - 4].length >= 3 && inhibs[iPositionMin - 4][2] != null) {
forceNotRecursive = inhibs[iPositionMin - 4][2].indexOf(TextSearch.FORCE_NOT_RECURSIVE) > -1;
} else {
forceNotRecursive = false;
}
pos = blockIndexEndIn(buffer, inhibs[iPositionMin - 4][0], inhibs[iPositionMin - 4][1], positions[iPositionMin].b(), posEnd, (recursiveInhibs && !forceNotRecursive) ? true : false,
spec, jump, (recursiveInhibs && !forceNotRecursive) ? inhibs : null).e();
}
if (nbBeginTagOuvert == 0) {
return positions[iPositionMin];
}
};
return Int2.NOT_FOUND;
}
/*
* (pos < 0 || (buffer.length()-pos) <= 0) => -1
*/
public Int2 lastIndexOf(final String buffer, final String tag) {
return lastIndexOf(buffer, tag, 0);
}
public Int2 lastIndexOf(final String buffer, final String tag, int pos) {
return lastIndexOf(buffer, tag, pos, null, null);
}
public Int2 lastIndexOf(final String buffer, final String tag, String spec, String[][] inhibs) {
return lastIndexOf(buffer, tag, 0, spec, inhibs);
}
public Int2 lastIndexOf(final String buffer, final String tag, int pos, String spec, String[][] inhibs) {
return lastIndexIn(buffer, tag, pos, buffer.length(), spec, inhibs);
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || posEnd >
* buffer.length()) => -1
*/
public Int2 lastIndexIn(final String buffer, final String tag, int posBegin, int posEnd) {
return lastIndexIn(buffer, tag, posBegin, posEnd, null, null);
}
public Int2 lastIndexIn(final String buffer, final String tag, int posBegin, int posEnd, String spec, String[][] inhibs) {
if (buffer == null || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return Int2.NOT_FOUND;
}
Int2 i = indexIn(buffer, tag, posBegin, posEnd, spec, inhibs);
Int2 last_i = i;
while (i.b() > -1) {
i = indexIn(buffer, tag, i.e(), posEnd, spec, inhibs);
if (i.b() > -1) {
last_i = i;
}
}
return last_i;
}
/*
* (pos < 0) => {}
*/
public Int2[] allIndexOf(final String buffer, final String tag) {
return allIndexOf(buffer, tag, 0);
}
public Int2[] allIndexOf(final String buffer, final String tag, int pos) {
return allIndexOf(buffer, tag, pos, null, null);
}
public Int2[] allIndexOf(final String buffer, final String tag, String spec, String[][] inhibs) {
return allIndexOf(buffer, tag, 0, spec, inhibs);
}
public Int2[] allIndexOf(final String buffer, final String tag, int pos, String spec, String[][] inhibs) {
return allIndexIn(buffer, tag, pos, buffer.length(), spec, inhibs);
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || (posEnd-posBegin) <=
* 0 || posEnd > buffer.length()) => {}
*/
public Int2[] allIndexIn(final String buffer, final String tag, int posBegin, int posEnd) {
return allIndexIn(buffer, tag, posBegin, posEnd, null, null);
}
public Int2[] allIndexIn(final String buffer, final String tag, int posBegin, int posEnd, String spec, String[][] inhibs) {
if (buffer == null || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return new Int2[] {};
}
List lst = new ArrayList();
Int2 i = indexIn(buffer, tag, posBegin, posEnd, spec, inhibs);
while (i.b() > -1) {
lst.add(i);
i = indexIn(buffer, tag, i.e(), posEnd, spec, inhibs);
}
return (Int2[]) lst.toArray(new Int2[lst.size()]);
}
public String[] splitOf(final String buffer, String[] separators, boolean keepSeparators) {
return splitOf(buffer, separators, keepSeparators, null, null);
}
public String[] splitOf(final String buffer, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
return splitOf(buffer, 0, separators, keepSeparators, spec, inhibs);
}
/*
* (posBegin < 0 || (buffer.length()-posBegin) <= 0) => {}
*/
public String[] splitOf(final String buffer, int posBegin, String[] separators, boolean keepSeparators) {
return splitOf(buffer, posBegin, separators, keepSeparators, null, null);
}
public String[] splitOf(final String buffer, int posBegin, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
return splitIn(buffer, posBegin, buffer.length(), separators, keepSeparators, spec, inhibs);
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || posEnd >
* buffer.length()) => {}
*/
public String[] splitIn(final String buffer, int posBegin, int posEnd, String[] separators, boolean keepSeparators) {
return splitIn(buffer, posBegin, posEnd, separators, keepSeparators, null, null);
}
public String[] splitIn(final String buffer, int posBegin, int posEnd, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
List list = split(buffer, posBegin, posEnd, separators, keepSeparators, spec, inhibs);
return (String[]) list.toArray(new String[list.size()]);
}
private List split(final String buffer, int posBegin, int posEnd, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
List result = new LinkedList();
if (buffer == null || buffer.length() == 0 || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return result;
}
if (separators == null) {
return result;
}
for (String separator : separators) {
if (separator != null && separator.length() > 0) {
Int2 index = indexIn(buffer, separator, posBegin, posEnd, spec, inhibs);
if (keepSeparators) {
if (index.b() == posBegin) {
return concat(buffer.substring(index.b(), index.e()), split(buffer, index.e(), posEnd, separators, keepSeparators, spec, inhibs));
} else if (index.e() == buffer.length()) {
return concat(split(buffer, posBegin, index.b(), separators, keepSeparators, spec, inhibs), buffer.substring(index.b(), index.e()));
} else if (index.b() > -1) {
return concat(split(buffer, posBegin, index.b(), separators, keepSeparators, spec, inhibs), buffer.substring(index.b(), index.e()),
split(buffer, index.e(), posEnd, separators, keepSeparators, spec, inhibs));
}
} else {
if (index.b() == 0) {
return split(buffer, index.e(), posEnd, separators, keepSeparators, spec, inhibs);
} else if (index.e() == buffer.length()) {
return split(buffer, posBegin, index.b(), separators, keepSeparators, spec, inhibs);
} else if (index.b() > -1) {
return concat(split(buffer, posBegin, index.b(), separators, keepSeparators, spec, inhibs), split(buffer, index.e(), posEnd, separators, keepSeparators, spec, inhibs));
}
}
}
}
result.add(buffer.substring(posBegin, posEnd));
return result;
}
public Int2[] splitPositionsOf(final String buffer, String[] separators, boolean keepSeparators) {
return splitPositionsOf(buffer, separators, keepSeparators, null, null);
}
public Int2[] splitPositionsOf(final String buffer, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
return splitPositionsOf(buffer, 0, separators, keepSeparators, spec, inhibs);
}
/*
* (posBegin < 0 || (buffer.length()-posBegin) <= 0) => {}
*/
public Int2[] splitPositionsOf(final String buffer, int posBegin, String[] separators, boolean keepSeparators) {
return splitPositionsOf(buffer, posBegin, separators, keepSeparators, null, null);
}
public Int2[] splitPositionsOf(final String buffer, int posBegin, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
return splitPositionsIn(buffer, posBegin, buffer.length(), separators, keepSeparators, spec, inhibs);
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || posEnd >
* buffer.length()) => {}
*/
public Int2[] splitPositionsIn(final String buffer, int posBegin, int posEnd, String[] separators, boolean keepSeparators) {
return splitPositionsIn(buffer, posBegin, posEnd, separators, keepSeparators, null, null);
}
public Int2[] splitPositionsIn(final String buffer, int posBegin, int posEnd, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
List list = splitPositions(buffer, posBegin, posEnd, separators, keepSeparators, spec, inhibs);
return (Int2[]) list.toArray(new Int2[list.size()]);
}
private List splitPositions(final String buffer, int posBegin, int posEnd, String[] separators, boolean keepSeparators, String spec, String[][] inhibs) {
List result = new LinkedList();
if (buffer == null || buffer.length() == 0 || posBegin < 0 || posEnd <= 0 || posEnd <= posBegin || posEnd > buffer.length()) {
return result;
}
if (separators == null) {
return result;
}
Int2[] positions = new Int2[separators.length];
for (int i = 0; i < positions.length; i++) {
positions[i] = new Int2(-2, -2);
}
while (posBegin > -1 && posBegin < posEnd) {
for (int i = 0; i < positions.length; i++) {
if (positions[i].b() != -1 && posBegin > positions[i].b()) {
if (separators[i] != null && separators[i].length() > 0) {
positions[i] = indexIn(buffer, separators[i], posBegin, posEnd, spec, inhibs);
} else {
positions[i] = Int2.NOT_FOUND;
}
}
}
// Get next position
int positionMin = posEnd;
int iPositionMin = -1;
for (int i = 0; i < positions.length; i++) {
if ((positions[i].b() > -1) && (positions[i].b() < positionMin)) {
iPositionMin = i;
positionMin = positions[i].b();
}
}
if (iPositionMin == -1 /* NOT FOUND */) {
if (posEnd > posBegin) {
result.add(new Int2(posBegin, posEnd));
}
break;
} else {
if (positions[iPositionMin].b() > posBegin) {
result.add(new Int2(posBegin, positions[iPositionMin].b()));
}
if (keepSeparators) {
result.add(positions[iPositionMin]);
}
posBegin = positions[iPositionMin].e();
}
}
return result;
}
private List concat(List t1, Object o, List t2) {
t1.add(o);
t1.addAll(t2);
return t1;
}
private List concat(List t1, List t2) {
t1.addAll(t2);
return t1;
}
private List concat(List t1, Object o) {
t1.add(o);
return t1;
}
private List concat(Object o, List t2) {
t2.add(0, o);
return t2;
}
/*
* Sample : <li> buffer =1:aaa.bbb </li> <li> sRegex = \[0-9]:ID.ID </li>
* <li> arg = ID </li> <li> argRegex = [a-zA-Z]+ </li> <p> => {aaa,bbb}
*/
public String[] extractValues(final String buffer, String sRegex, String arg, String argRegex) {
if (buffer == null || sRegex == null || arg == null || argRegex == null) {
return new String[] {};
}
List res = new ArrayList();
String[] regex = splitOf(sRegex, new String[] { arg }, true/* keepSeparators */, null, null);
boolean posOK = true;
int iPosOK = 0;
for (int i = 0; posOK && i < regex.length; i++) {
String ex = regex[i];
boolean isArg = ex.equals(arg);
if (isArg) {
ex = argRegex;
}
Int2 pos = indexOf(buffer, ex, iPosOK);
if (isArg) {
res.add(buffer.substring(pos.b(), pos.e()));
}
posOK = (pos.b() == iPosOK);
iPosOK = pos.e();
}
posOK = (iPosOK == buffer.length());
if (posOK) {
return (String[]) res.toArray(new String[res.size()]);
} else {
return new String[] {};
}
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || posEnd >
* buffer.length()) => -1
*/
public Int2 trim(final String buffer, int posBegin, int posEnd) {
if (buffer == null) {
return Int2.NOT_FOUND;
}
if (posBegin < 0 || posBegin >= buffer.length()) {
return Int2.NOT_FOUND;
}
if (posEnd < 0 || posEnd > buffer.length()) {
return Int2.NOT_FOUND;
}
if (posBegin > posEnd) {
return Int2.NOT_FOUND;
}
while (posBegin < posEnd) {
char c = buffer.charAt(posBegin);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
posBegin++;
} else {
break;
}
}
while (posEnd > posBegin) {
char c = buffer.charAt(posEnd - 1);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
posEnd--;
} else {
break;
}
}
if (posBegin < posEnd) {
return new Int2(posBegin, posEnd);
} else {
return Int2.NOT_FOUND;
}
}
/*
* (pos < 0) => 0
*/
public int countOf(final String buffer, final String tag) {
return countOf(buffer, tag, 0);
}
public int countOf(final String buffer, final String tag, int pos) {
return countOf(buffer, tag, pos, null, null);
}
public int countOf(final String buffer, final String tag, String spec, String[][] inhibs) {
return countOf(buffer, tag, 0, spec, inhibs);
}
public int countOf(final String buffer, final String tag, int pos, String spec, String[][] inhibs) {
return countIn(buffer, tag, pos, buffer.length(), spec, inhibs);
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || (posEnd-posBegin) <=
* 0 || posEnd > buffer.length()) => 0
*/
public int countIn(final String buffer, final String tag, int posBegin, int posEnd) {
return countIn(buffer, tag, posBegin, posEnd, null, null);
}
public int countIn(final String buffer, final String tag, int posBegin, int posEnd, String spec, String[][] inhibs) {
return allIndexIn(buffer, tag, posBegin, posEnd, spec, inhibs).length;
}
/*
* (buffer == null || index < 0 || index > buffer.length()) => 0
*/
public int lineNumber(File file, int index) {
Object[] object = (Object[]) lineNumberFileContentMap.get(file);
if (object == null) {
object = new Object[2];
object[0] = new HashMap();
((Map) object[0]).put(new Integer(0), new Integer(1));
String buffer = Resources.getFileContent(file).toString();
object[1] = buffer;
Int2[] endLines = allIndexOf(buffer, "\n"); //$NON-NLS-1$
for (int i = 0; i < endLines.length; i++) {
((Map) object[0]).put(new Integer(endLines[i].e()), new Integer(i + 2));
}
lineNumberFileContentMap.put(file, object);
}
Map firstCharToLine = (Map) object[0];
String buffer = (String) object[1];
int firstChar = index;
while (firstChar > 0 && buffer.charAt(firstChar - 1) != '\n') {
firstChar--;
}
Integer lineNumber = (Integer) firstCharToLine.get(new Integer(firstChar));
if (lineNumber != null) {
return lineNumber.intValue();
} else {
AcceleoToolsPlugin.getDefault().log(AcceleoToolsMessages.getString("TextSearch.CharacterLineNotFound", new Object[] { Integer.toString(index), file.getAbsolutePath(), }), true); //$NON-NLS-1$
return 0;
}
}
private FileContentMap lineNumberFileContentMap = new FileContentMap(5, true);
/*
* (buffer == null || index < 0 || index > buffer.length()) => 0
*/
public int lineNumber(final String buffer, int index) {
if (buffer != null && index >= 0 && index < buffer.length()) {
if (refBuffer.equals(buffer) && index >= refIndex) {
for (int i = refIndex; i < index; i++) {
if (buffer.charAt(i) == '\n') {
refLineNumber++;
}
}
} else {
refLineNumber = 1;
for (int i = 0; i < index; i++) {
if (buffer.charAt(i) == '\n') {
refLineNumber++;
}
}
}
refBuffer = buffer;
refIndex = index;
return refLineNumber;
} else {
return 0;
}
}
private String refBuffer = ""; //$NON-NLS-1$
private int refIndex = 0;
private int refLineNumber = 1;
/*
* (buffer == null || index <= 0 || index > buffer.length()) => 0
*/
public int columnNumber(final String buffer, int index) {
if (buffer != null && index > 0 && index < buffer.length()) {
int column = 0;
for (int i = index - 1; i >= 0; i--) {
if (buffer.charAt(i) != '\n') {
column++;
} else {
break;
}
}
return column;
} else {
return 0;
}
}
/*
* (posBegin < 0 || posEnd < 0 || posEnd <= posBegin || posEnd >
* buffer.length()) => buffer
*/
public String replaceAllIn(final String buffer, String string, String replacementString, int posBegin, int posEnd, String[][] inhibs) {
if (buffer == null) {
return null;
}
StringBuffer result = new StringBuffer(buffer);
Int2[] positions = allIndexIn(buffer, string, posBegin, posEnd, null, inhibs);
if (positions.length > 0) {
for (int i = positions.length - 1; i >= 0; i--) {
Int2 pos = positions[i];
result.replace(pos.b(), pos.e(), replacementString);
}
}
return result.toString();
}
}