PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sys/java/fan/sys/Depend.java

https://bitbucket.org/bedlaczech/fan-1.0
Java | 303 lines | 237 code | 35 blank | 31 comment | 47 complexity | 28d1964128efba4e10ce2b3e2aabd43d MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //
  2. // Copyright (c) 2006, Brian Frank and Andy Frank
  3. // Licensed under the Academic Free License version 3.0
  4. //
  5. // History:
  6. // 3 Nov 06 Brian Frank Creation
  7. //
  8. package fan.sys;
  9. import java.util.*;
  10. /**
  11. * Depend
  12. */
  13. public final class Depend
  14. extends FanObj
  15. {
  16. //////////////////////////////////////////////////////////////////////////
  17. // Construction
  18. //////////////////////////////////////////////////////////////////////////
  19. public static Depend fromStr(String str) { return fromStr(str, true); }
  20. public static Depend fromStr(String str, boolean checked)
  21. {
  22. try
  23. {
  24. return new Parser(str).parse();
  25. }
  26. catch (Throwable e)
  27. {
  28. if (!checked) return null;
  29. throw ParseErr.make("Depend", str);
  30. }
  31. }
  32. private Depend(String name, Constraint[] constraints)
  33. {
  34. this.name = name;
  35. this.constraints = constraints;
  36. }
  37. //////////////////////////////////////////////////////////////////////////
  38. // Parser
  39. //////////////////////////////////////////////////////////////////////////
  40. static class Parser
  41. {
  42. Parser(String str)
  43. {
  44. this.str = str;
  45. this.len = str.length();
  46. consume();
  47. }
  48. Depend parse()
  49. {
  50. name = name();
  51. constraints.add(constraint());
  52. while (cur == ',')
  53. {
  54. consume();
  55. consumeSpaces();
  56. constraints.add(constraint());
  57. }
  58. if (pos <= len) throw new RuntimeException();
  59. return new Depend(name, (Constraint[])constraints .toArray(new Constraint[constraints.size()]));
  60. }
  61. private String name()
  62. {
  63. StringBuilder s = new StringBuilder();
  64. while (cur != ' ')
  65. {
  66. if (cur < 0) throw new RuntimeException();
  67. s.append((char)cur);
  68. consume();
  69. }
  70. consumeSpaces();
  71. if (s.length() == 0) throw new RuntimeException();
  72. return s.toString();
  73. }
  74. private Constraint constraint()
  75. {
  76. Constraint c = new Constraint();
  77. c.version = version();
  78. consumeSpaces();
  79. if (cur == '+')
  80. {
  81. c.isPlus = true;
  82. consume();
  83. consumeSpaces();
  84. }
  85. else if (cur == '-')
  86. {
  87. consume();
  88. consumeSpaces();
  89. c.endVersion = version();
  90. consumeSpaces();
  91. }
  92. return c;
  93. }
  94. private Version version()
  95. {
  96. List segs = new List(Sys.IntType, 4);
  97. int seg = consumeDigit();
  98. while (true)
  99. {
  100. if ('0' <= cur && cur <= '9')
  101. {
  102. seg = seg*10 + consumeDigit();
  103. }
  104. else
  105. {
  106. segs.add(Long.valueOf(seg));
  107. seg = 0;
  108. if (cur != '.') break;
  109. else consume();
  110. }
  111. }
  112. return new Version(segs);
  113. }
  114. private int consumeDigit()
  115. {
  116. if ('0' <= cur && cur <= '9')
  117. {
  118. int digit = cur - '0';
  119. consume();
  120. return digit;
  121. }
  122. throw new RuntimeException();
  123. }
  124. private void consumeSpaces()
  125. {
  126. while (cur == ' ') consume();
  127. }
  128. private void consume()
  129. {
  130. if (pos < len)
  131. {
  132. cur = str.charAt(pos++);
  133. }
  134. else
  135. {
  136. cur = -1;
  137. pos = len+1;
  138. }
  139. }
  140. int cur;
  141. int pos;
  142. int len;
  143. String str;
  144. String name;
  145. ArrayList constraints = new ArrayList(4);
  146. }
  147. //////////////////////////////////////////////////////////////////////////
  148. // Identity
  149. //////////////////////////////////////////////////////////////////////////
  150. public boolean equals(Object obj)
  151. {
  152. if (obj instanceof Depend)
  153. return toStr().equals(toStr(obj));
  154. else
  155. return false;
  156. }
  157. public int hashCode()
  158. {
  159. return toStr().hashCode();
  160. }
  161. public long hash()
  162. {
  163. return FanStr.hash(toStr());
  164. }
  165. public Type typeof()
  166. {
  167. return Sys.DependType;
  168. }
  169. public String toStr()
  170. {
  171. if (str == null)
  172. {
  173. StringBuilder s = new StringBuilder();
  174. s.append(name).append(' ');
  175. for (int i=0; i<constraints.length; ++i)
  176. {
  177. if (i > 0) s.append(',');
  178. Constraint c = constraints[i];
  179. s.append(c.version);
  180. if (c.isPlus) s.append('+');
  181. if (c.endVersion != null) s.append('-').append(c.endVersion);
  182. }
  183. str = s.toString();
  184. }
  185. return str;
  186. }
  187. //////////////////////////////////////////////////////////////////////////
  188. // Methods
  189. //////////////////////////////////////////////////////////////////////////
  190. public final String name()
  191. {
  192. return name;
  193. }
  194. public final long size()
  195. {
  196. return constraints.length;
  197. }
  198. public final Version version() { return version(0L); }
  199. public final Version version(long index)
  200. {
  201. return constraints[(int)index].version;
  202. }
  203. public final boolean isPlus() { return isPlus(0L); }
  204. public final boolean isPlus(long index)
  205. {
  206. return constraints[(int)index].isPlus;
  207. }
  208. public final boolean isRange() { return isRange(0L); }
  209. public final boolean isRange(long index)
  210. {
  211. return constraints[(int)index].endVersion != null;
  212. }
  213. public final Version endVersion() { return endVersion(0L); }
  214. public final Version endVersion(long index)
  215. {
  216. return constraints[(int)index].endVersion;
  217. }
  218. public final boolean match(Version v)
  219. {
  220. for (int i=0; i<constraints.length; ++i)
  221. {
  222. Constraint c = constraints[i];
  223. if (c.isPlus)
  224. {
  225. // versionPlus
  226. if (c.version.compare(v) <= 0)
  227. return true;
  228. }
  229. else if (c.endVersion != null)
  230. {
  231. // versionRange
  232. if (c.version.compare(v) <= 0 &&
  233. (c.endVersion.compare(v) >= 0 || doMatch(c.endVersion, v)))
  234. return true;
  235. }
  236. else
  237. {
  238. // versionSimple
  239. if (doMatch(c.version, v))
  240. return true;
  241. }
  242. }
  243. return false;
  244. }
  245. private static boolean doMatch(Version a, Version b)
  246. {
  247. if (a.segments().sz() > b.segments().sz()) return false;
  248. for (int i=0; i<a.segments().sz(); ++i)
  249. if (a.segment(i) != b.segment(i))
  250. return false;
  251. return true;
  252. }
  253. //////////////////////////////////////////////////////////////////////////
  254. // Constraint
  255. //////////////////////////////////////////////////////////////////////////
  256. static class Constraint
  257. {
  258. Version version;
  259. boolean isPlus;
  260. Version endVersion;
  261. }
  262. //////////////////////////////////////////////////////////////////////////
  263. // Fields
  264. //////////////////////////////////////////////////////////////////////////
  265. private final String name;
  266. private final Constraint[] constraints;
  267. private String str;
  268. }