/plugins/org.integratedmodelling.thinklab.core/src/org/integratedmodelling/utils/WildcardMatcher.java

https://github.com/ariesteam/thinklab · Java · 296 lines · 184 code · 11 blank · 101 comment · 49 complexity · b11f5503a9fea32a9d7e047da9751839 MD5 · raw file

  1. /**
  2. * Copyright 2011 The ARIES Consortium (http://www.ariesonline.org) and
  3. * www.integratedmodelling.org.
  4. This file is part of Thinklab.
  5. Thinklab is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published
  7. by the Free Software Foundation, either version 3 of the License,
  8. or (at your option) any later version.
  9. Thinklab is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Thinklab. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. package org.integratedmodelling.utils;
  17. import java.util.Vector;
  18. /**This class is a utility for finding
  19. * the String based upon the wild card
  20. * pattern. For example if the actual
  21. * String "John" and your wild card pattern
  22. * is "J*", it will return true.
  23. * @author Debadatta Mishra(PIKU)
  24. *
  25. * TODO make it static and stateless - do away with the silly object semantics.
  26. */
  27. public class WildcardMatcher
  28. {
  29. /**
  30. * String variable for wild card pattern
  31. */
  32. private String wildCardPatternString;
  33. /**
  34. * Variable for the length of the wild card pattern
  35. */
  36. private int wildCardPatternLength;
  37. /**
  38. * Boolean variable to for checking wild cards,
  39. * It is false by default.
  40. */
  41. private boolean ignoreWildCards;
  42. /**
  43. * Boolean variable to know whether the pattern
  44. * has leading * or not.
  45. */
  46. private boolean hasLeadingStar;
  47. /**
  48. * Boolean variable to know whether the pattern
  49. * has * at the end.
  50. */
  51. private boolean hasTrailingStar;
  52. /**
  53. * A String array to contain chars
  54. */
  55. private String charSegments[];
  56. /**
  57. * Variable to maintain the boundary of the String.
  58. */
  59. private int charBound;
  60. /**
  61. * Default constructor
  62. */
  63. public WildcardMatcher()
  64. {
  65. ignoreWildCards = false;
  66. }
  67. /**This is the public method which will be called to match a String
  68. * with the wild card pattern.
  69. * @param actualString of type String indicating the String to be matched
  70. * @param wildCardString of type String indicating the wild card String
  71. * @return true if matches
  72. */
  73. public boolean match(String actualString , String wildCardString )
  74. {
  75. wildCardPatternString = wildCardString;
  76. wildCardPatternLength = wildCardString.length();
  77. setWildCards();
  78. return doesMatch( actualString, 0, actualString.length() );
  79. }
  80. /**
  81. * This method is used to set the wild cards.
  82. * The pattern for the wild card may be *, ? or
  83. * a combination of *,? and alphanumeric character.
  84. */
  85. private void setWildCards()
  86. {
  87. if(wildCardPatternString.startsWith("*"))
  88. {
  89. hasLeadingStar = true;
  90. }
  91. if (wildCardPatternString.endsWith("*") && wildCardPatternLength > 1 )
  92. {
  93. hasTrailingStar = true;
  94. }
  95. Vector temp = new Vector();
  96. int pos = 0;
  97. StringBuffer buf = new StringBuffer();
  98. while(pos < wildCardPatternLength)
  99. {
  100. char c = wildCardPatternString.charAt(pos++);
  101. switch(c)
  102. {
  103. case 42: // It refers to *
  104. if(buf.length() > 0)
  105. {
  106. temp.addElement(buf.toString());
  107. charBound += buf.length();
  108. buf.setLength(0);
  109. }
  110. break;
  111. case 63: // It refers to ?
  112. buf.append('\0');
  113. break;
  114. default:
  115. buf.append(c);
  116. break;
  117. }
  118. }
  119. if(buf.length() > 0)
  120. {
  121. temp.addElement(buf.toString());
  122. charBound += buf.length();
  123. }
  124. charSegments = new String[temp.size()];
  125. temp.copyInto(charSegments);
  126. }
  127. /**This is the actual method which makes comparison
  128. * with the wild card pattern.
  129. * @param text of type String indicating the actual String
  130. * @param startPoint of type int indicating the start index
  131. * of the String
  132. * @param endPoint of type int indicating the end index of
  133. * the String
  134. * @return true if matches.
  135. */
  136. private final boolean doesMatch(String text, int startPoint, int endPoint)
  137. {
  138. int textLength = text.length();
  139. if(startPoint > endPoint)
  140. {
  141. return false;
  142. }
  143. if(ignoreWildCards)
  144. {
  145. return endPoint - startPoint == wildCardPatternLength
  146. && wildCardPatternString.regionMatches(false, 0, text,
  147. startPoint, wildCardPatternLength);
  148. }
  149. int charCount = charSegments.length;
  150. if(charCount == 0 && ( hasLeadingStar || hasTrailingStar ) )
  151. {
  152. return true;
  153. }
  154. if(startPoint == endPoint)
  155. {
  156. return wildCardPatternLength == 0;
  157. }
  158. if(wildCardPatternLength == 0)
  159. {
  160. return startPoint == endPoint;
  161. }
  162. if(startPoint < 0)
  163. {
  164. startPoint = 0;
  165. }
  166. if(endPoint > textLength)
  167. {
  168. endPoint = textLength;
  169. }
  170. int currPosition = startPoint;
  171. int bound = endPoint - charBound;
  172. if(bound < 0)
  173. {
  174. return false;
  175. }
  176. int i = 0;
  177. String currString = charSegments[i];
  178. int currStringLength = currString.length();
  179. if( !hasLeadingStar )
  180. {
  181. if(!isExpressionMatching(text, startPoint,
  182. currString, 0, currStringLength))
  183. {
  184. return false;
  185. }
  186. i++;
  187. currPosition += currStringLength;
  188. }
  189. if(charSegments.length == 1 && !hasLeadingStar && !hasTrailingStar)
  190. {
  191. return currPosition == endPoint;
  192. }
  193. for(; i < charCount; i++)
  194. {
  195. currString = charSegments[i];
  196. int k = currString.indexOf('\0');
  197. int currentMatch;
  198. currentMatch = getTextPosition(text, currPosition,
  199. endPoint, currString);
  200. if(k < 0)
  201. {
  202. if(currentMatch < 0)
  203. {
  204. return false;
  205. }
  206. }
  207. currPosition = currentMatch + currString.length();
  208. }
  209. if(!hasTrailingStar && currPosition != endPoint)
  210. {
  211. int clen = currString.length();
  212. return isExpressionMatching(text,
  213. endPoint - clen, currString, 0, clen);
  214. }
  215. return i == charCount;
  216. }
  217. /**This method finds the position of the String based upon the
  218. * wild card pattern. It also considers some special case
  219. * like *.* and ???.? and their combination.
  220. * @param textString of type String indicating the String
  221. * @param start of type int indicating the start index of the String
  222. * @param end of type int indicating the end index of the String
  223. * @param posString of type indicating the position after wild card
  224. * @return the position of the String
  225. */
  226. private final int getTextPosition(String textString, int start,
  227. int end, String posString)
  228. {
  229. /*
  230. * String after *
  231. */
  232. int plen = posString.length();
  233. int max = end - plen;
  234. int position = -1;
  235. int i = textString.indexOf(posString, start);
  236. /*
  237. * The following conditions are met for the
  238. * special case where user give *.*
  239. */
  240. if( posString.equals("."))
  241. {
  242. position = 1;
  243. }
  244. if(i == -1 || i > max)
  245. {
  246. position = -1;
  247. }
  248. else
  249. {
  250. position = i;
  251. }
  252. return position;
  253. }
  254. /**This method is used to match the wild card with the String
  255. * based upon the start and end index.
  256. * @param textString of type String indicating the String
  257. * @param stringStartIndex of type int indicating the start
  258. * index of the String.
  259. * @param patternString of type String indicating the pattern
  260. * @param patternStartIndex of type int indicating the start index
  261. * @param length of type int indicating the length of pattern
  262. * @return true if matches otherwise false
  263. */
  264. private boolean isExpressionMatching(String textString, int stringStartIndex,
  265. String patternString, int patternStartIndex, int length)
  266. {
  267. while(length-- > 0)
  268. {
  269. char textChar = textString.charAt(stringStartIndex++);
  270. char patternChar = patternString.charAt(patternStartIndex++);
  271. if ((ignoreWildCards || patternChar != 0)
  272. && patternChar != textChar
  273. && (textChar != patternChar
  274. && textChar != patternChar))
  275. {
  276. return false;
  277. }
  278. }
  279. return true;
  280. }
  281. }