Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

google app engine deployable jruby sinatra application

  • Loading branch information...
commit 5d36d2bc8619d0b26d38939eff099e14478f5d5c 1 parent 6cd66b6
Sammy Zahabi authored
Showing with 43,613 additions and 0 deletions.
  1. +27 −0 Capfile
  2. +10 −0 app.rb
  3. +22 −0 appengine-web.xml
  4. +15 −0 config.ru
  5. +96 −0 config/warble.rb
  6. BIN  lib/appengine-api-1.0-sdk-1.2.0.jar
  7. BIN  lib/jruby-core.jar
  8. BIN  lib/jruby-rack-0.9.4.jar
  9. BIN  lib/ruby-stdlib.jar
  10. +24 −0 lib/split-jruby.sh
  11. BIN  test.war
  12. +10 −0 tmp/war/WEB-INF/app.rb
  13. +22 −0 tmp/war/WEB-INF/appengine-web.xml
  14. +14 −0 tmp/war/WEB-INF/config.ru
  15. +62 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/CHANGELOG
  16. +18 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/COPYING
  17. +284 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/README
  18. +262 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/Rakefile
  19. +1,018 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/fast_xs/FastXsService.java
  20. +4 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/fast_xs/extconf.rb
  21. +194 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/fast_xs/fast_xs.c
  22. +1,301 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/HpricotScanService.java
  23. +6 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/extconf.rb
  24. +76 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_common.rl
  25. +882 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_gram.c
  26. +9 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_gram.h
  27. +6,261 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_scan.c
  28. +79 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_scan.h
  29. +369 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_scan.java.rl
  30. +279 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/hpricot_scan.rl
  31. +5 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/hpricot_scan/test.rb
  32. +176 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/extras/mingw-rbconfig.rb
  33. +26 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot.rb
  34. +63 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/blankslate.rb
  35. +215 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/builder.rb
  36. +510 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/elements.rb
  37. +672 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/htmlinfo.rb
  38. +107 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/inspect.rb
  39. +37 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/modules.rb
  40. +298 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/parse.rb
  41. +232 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/tag.rb
  42. +164 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/tags.rb
  43. +832 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/traverse.rb
  44. +94 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/hpricot/xchar.rb
  45. BIN  tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/universal-java1.6/fast_xs.jar
  46. BIN  tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/lib/universal-java1.6/hpricot_scan.jar
  47. +17 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/basic.xhtml
  48. +2,266 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/boingboing.html
  49. +3,653 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/cy0.html
  50. +400 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/immob.html
  51. +1,320 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/pace_application.html
  52. +16 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/tenderlove.html
  53. +220 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/uswebgen.html
  54. +1,054 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/utf8.html
  55. +1,723 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/week9.html
  56. +19 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/files/why.xml
  57. +7 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/load_files.rb
  58. +77 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/test_alter.rb
  59. +37 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/test_builder.rb
  60. +386 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/test_parser.rb
  61. +25 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/test_paths.rb
  62. +66 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/test_preserved.rb
  63. +28 −0 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/test/test_xml.rb
  64. +18 −0 tmp/war/WEB-INF/gems/gems/pipe-0.1.3/History.txt
  65. +5 −0 tmp/war/WEB-INF/gems/gems/pipe-0.1.3/Manifest.txt
  66. +97 −0 tmp/war/WEB-INF/gems/gems/pipe-0.1.3/README.txt
  67. +13 −0 tmp/war/WEB-INF/gems/gems/pipe-0.1.3/Rakefile
  68. +39 −0 tmp/war/WEB-INF/gems/gems/pipe-0.1.3/lib/pipe.rb
  69. +8 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/AUTHORS
  70. +18 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/COPYING
  71. +18 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/KNOWN-ISSUES
  72. +324 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/RDOX
  73. +306 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/README
  74. +188 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/Rakefile
  75. +129 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/SPEC
  76. +172 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/bin/rackup
  77. +111 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/contrib/rack_logo.svg
  78. +4 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/example/lobster.ru
  79. +14 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/example/protectedlobster.rb
  80. +8 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/example/protectedlobster.ru
  81. +86 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack.rb
  82. +22 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/adapter/camping.rb
  83. +28 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/abstract/handler.rb
  84. +37 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/abstract/request.rb
  85. +58 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/basic.rb
  86. +124 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/digest/md5.rb
  87. +51 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/digest/nonce.rb
  88. +55 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/digest/params.rb
  89. +40 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/digest/request.rb
  90. +438 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/auth/openid.rb
  91. +67 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/builder.rb
  92. +36 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/cascade.rb
  93. +61 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/commonlogger.rb
  94. +43 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/conditionalget.rb
  95. +25 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/content_length.rb
  96. +87 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/deflater.rb
  97. +150 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/directory.rb
  98. +85 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/file.rb
  99. +48 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler.rb
  100. +57 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/cgi.rb
  101. +8 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/evented_mongrel.rb
  102. +86 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/fastcgi.rb
  103. +52 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/lsws.rb
  104. +82 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/mongrel.rb
  105. +57 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/scgi.rb
  106. +8 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb
  107. +15 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/thin.rb
  108. +61 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/handler/webrick.rb
  109. +19 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/head.rb
  110. +465 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/lint.rb
  111. +65 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/lobster.rb
  112. +27 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/methodoverride.rb
  113. +204 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/mime.rb
  114. +160 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/mock.rb
  115. +57 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/recursive.rb
  116. +64 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/reloader.rb
  117. +218 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/request.rb
  118. +171 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/response.rb
  119. +153 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/session/abstract/id.rb
  120. +89 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/session/cookie.rb
  121. +97 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/session/memcache.rb
  122. +73 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/session/pool.rb
  123. +348 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/showexceptions.rb
  124. +106 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/showstatus.rb
  125. +38 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/static.rb
  126. +48 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/urlmap.rb
  127. +347 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/lib/rack/utils.rb
  128. +20 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/cgi/lighttpd.conf
  129. +9 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/cgi/test
  130. +8 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/cgi/test.fcgi
  131. +7 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/cgi/test.ru
  132. +69 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_auth_basic.rb
  133. +169 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_auth_digest.rb
  134. +137 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_auth_openid.rb
  135. +84 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_builder.rb
  136. +51 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_camping.rb
  137. +50 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_cascade.rb
  138. +89 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_cgi.rb
  139. +32 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_commonlogger.rb
  140. +41 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_conditionalget.rb
  141. +43 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_content_length.rb
  142. +105 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_deflater.rb
  143. +61 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_directory.rb
  144. +89 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_fastcgi.rb
  145. +64 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_file.rb
  146. +24 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_handler.rb
  147. +30 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_head.rb
  148. +380 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_lint.rb
  149. +45 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_lobster.rb
  150. +60 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_methodoverride.rb
  151. +152 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_mock.rb
  152. +189 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_mongrel.rb
  153. +77 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_recursive.rb
  154. +446 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_request.rb
  155. +174 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_response.rb
  156. +82 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_session_cookie.rb
  157. +132 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_session_memcache.rb
  158. +84 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_session_pool.rb
  159. +21 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_showexceptions.rb
  160. +72 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_showstatus.rb
  161. +37 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_static.rb
  162. +90 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_thin.rb
  163. +175 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_urlmap.rb
  164. +176 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_utils.rb
  165. +123 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/spec_rack_webrick.rb
  166. +57 −0 tmp/war/WEB-INF/gems/gems/rack-0.9.1/test/testrequest.rb
  167. +41 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/AUTHORS
  168. +287 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/CHANGES
  169. +22 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/LICENSE
  170. +483 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/README.rdoc
  171. +136 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/Rakefile
  172. +282 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/app_test.rb
  173. +262 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/application_test.rb
  174. +101 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/builder_test.rb
  175. +12 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/compat_test.rb
  176. +62 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/custom_error_test.rb
  177. +136 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/erb_test.rb
  178. +78 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/events_test.rb
  179. +30 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/filter_test.rb
  180. +233 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/haml_test.rb
  181. +30 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/helper.rb
  182. +72 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/mapped_error_test.rb
  183. +45 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/pipeline_test.rb
  184. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/public/foo.xml
  185. +57 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/sass_test.rb
  186. +42 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/sessions_test.rb
  187. +133 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/streaming_test.rb
  188. +19 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/sym_params_test.rb
  189. +30 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/template_test.rb
  190. +47 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/use_in_file_templates_test.rb
  191. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/foo.builder
  192. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/foo.erb
  193. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/foo.haml
  194. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/foo.sass
  195. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/foo_layout.erb
  196. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/foo_layout.haml
  197. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/foo.builder
  198. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/foo.erb
  199. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/foo.haml
  200. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/foo.sass
  201. +3 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/layout.builder
  202. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/layout.erb
  203. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/layout.haml
  204. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/layout_test/layout.sass
  205. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/no_layout/no_layout.builder
  206. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/compat/views/no_layout/no_layout.haml
  207. +8 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra.rb
  208. +1,026 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/base.rb
  209. +250 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/compat.rb
  210. BIN  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/images/404.png
  211. BIN  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/images/500.png
  212. +47 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/main.rb
  213. +126 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/test.rb
  214. +19 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/test/bacon.rb
  215. +13 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/test/rspec.rb
  216. +11 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/test/spec.rb
  217. +13 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra/test/unit.rb
  218. +115 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/sinatra.gemspec
  219. +130 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/base_test.rb
  220. +64 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/builder_test.rb
  221. +3 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/data/reload_app_file.rb
  222. +81 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/erb_test.rb
  223. +84 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/extensions_test.rb
  224. +99 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/filter_test.rb
  225. +68 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/haml_test.rb
  226. +81 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/helper.rb
  227. +497 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/helpers_test.rb
  228. +160 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/mapped_error_test.rb
  229. +68 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/middleware_test.rb
  230. +374 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/options_test.rb
  231. +68 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/reload_test.rb
  232. +18 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/request_test.rb
  233. +42 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/response_test.rb
  234. +98 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/result_test.rb
  235. +712 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/routing_test.rb
  236. +36 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/sass_test.rb
  237. +41 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/server_test.rb
  238. +13 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/sinatra_test.rb
  239. +80 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/static_test.rb
  240. +88 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/templates_test.rb
  241. +144 −0 tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/test_test.rb
  242. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/hello.builder
  243. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/hello.erb
  244. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/hello.haml
  245. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/hello.sass
  246. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/hello.test
  247. +3 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/layout2.builder
  248. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/layout2.erb
  249. +2 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/layout2.haml
  250. +1 −0  tmp/war/WEB-INF/gems/gems/sinatra-0.9.1.1/test/views/layout2.test
  251. +31 −0 tmp/war/WEB-INF/gems/specifications/hpricot-0.6.164-java.gemspec
  252. +39 −0 tmp/war/WEB-INF/gems/specifications/pipe-0.1.3.gemspec
  253. +33 −0 tmp/war/WEB-INF/gems/specifications/rack-0.9.1.gemspec
  254. +35 −0 tmp/war/WEB-INF/gems/specifications/sinatra-0.9.1.1.gemspec
  255. BIN  tmp/war/WEB-INF/lib/appengine-api-1.0-sdk-1.2.0.jar
  256. BIN  tmp/war/WEB-INF/lib/jruby-core.jar
  257. BIN  tmp/war/WEB-INF/lib/jruby-rack-0.9.4.jar
  258. BIN  tmp/war/WEB-INF/lib/ruby-stdlib.jar
  259. +24 −0 tmp/war/WEB-INF/lib/split-jruby.sh
  260. +65 −0 tmp/war/WEB-INF/web.xml
View
27 Capfile
@@ -0,0 +1,27 @@
+load 'deploy' if respond_to?(:namespace) # cap2 differentiator
+
+set :application, "montrealwebpresence.net"
+set :user, "szahabi "
+set :repository, "git@github.com:Thamster/peyepr.git"
+set :checkout, :export
+
+set :deploy_to, "/home/#{user}/#{application}/capTemp"
+set :deploy_via, :remote_cache
+
+set :scm, :git
+set :git_shallow_clone,1
+set :branch, "master"
+
+role :app, application
+role :web, application
+
+set :runner, user
+set :use_sudo, false
+
+namespace :deploy do
+ desc "Restart Application"
+ task :restart do
+ run "touch #{current_path}/tmp/restart.txt"
+ end
+end
+
View
10 app.rb
@@ -0,0 +1,10 @@
+require 'rubygems'
+require 'sinatra'
+require 'pipe'
+
+get '/' do
+ Pipe.create do
+ feed "http://www.reddit.com/r/programming/.rss", :title => /clojure/i
+ end
+end
+
View
22 appengine-web.xml
@@ -0,0 +1,22 @@
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+ <application>peyepr</application>
+ <version>1</version>
+ <static-files />
+ <resource-files />
+ <sessions-enabled>false</sessions-enabled>
+ <system-properties>
+ <property name="jruby.management.enabled" value="false" />
+ <property name="os.arch" value="" />
+ <property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
+ <property name="jruby.compile.fastest" value="true"/>
+ <property name="jruby.compile.frameless" value="true"/>
+ <property name="jruby.compile.positionless" value="true"/>
+ <property name="jruby.compile.threadless" value="false"/>
+ <property name="jruby.compile.fastops" value="false"/>
+ <property name="jruby.compile.fastcase" value="false"/>
+ <property name="jruby.compile.chainsize" value="500"/>
+ <property name="jruby.compile.lazyHandles" value="false"/>
+ <property name="jruby.compile.peephole" value="true"/>
+ </system-properties>
+</appengine-web-app>
+
View
15 config.ru
@@ -0,0 +1,15 @@
+require 'rubygems'
+gem 'sinatra', '=0.3.2'
+require 'sinatra'
+
+root_dir = File.dirname(__FILE__)
+
+set :environment, :production
+set :root, root_dir
+set :app_file, File.join(root_dir, 'app.rb')
+disable :run
+
+require 'app'
+
+run Sinatra::Application
+
View
96 config/warble.rb
@@ -0,0 +1,96 @@
+# Disable automatic framework detection by uncommenting/setting to false
+# Warbler.framework_detection = false
+
+# Warbler web application assembly configuration file
+Warbler::Config.new do |config|
+ # Temporary directory where the application is staged
+ # config.staging_dir = "tmp/war"
+
+ # Application directories to be included in the webapp.
+ config.dirs = %w(lib public views)
+
+ # Additional files/directories to include, above those in config.dirs
+ # config.includes = FileList["db"]
+ config.includes = FileList["appengine-web.xml", "app.rb", "config.ru"]
+ # Additional files/directories to exclude
+ # config.excludes = FileList["lib/tasks/*"]
+
+ # Additional Java .jar files to include. Note that if .jar files are placed
+ # in lib (and not otherwise excluded) then they need not be mentioned here.
+ # JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your
+ # own versions if you directly set the value
+ # config.java_libs += FileList["lib/java/*.jar"]
+
+ # Loose Java classes and miscellaneous files to be placed in WEB-INF/classes.
+ # config.java_classes = FileList["target/classes/**.*"]
+
+ # One or more pathmaps defining how the java classes should be copied into
+ # WEB-INF/classes. The example pathmap below accompanies the java_classes
+ # configuration above. See http://rake.rubyforge.org/classes/String.html#M000017
+ # for details of how to specify a pathmap.
+ # config.pathmaps.java_classes << "%{target/classes/,}p"
+
+ # Gems to be included. You need to tell Warbler which gems your application needs
+ # so that they can be packaged in the war file.
+ # The Rails gems are included by default unless the vendor/rails directory is present.
+ # config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"]
+ # config.gems << "tzinfo"
+ config.gems = ['sinatra', 'pipe']
+
+ # Uncomment this if you don't want to package rails gem.
+ # config.gems -= ["rails"]
+
+ # The most recent versions of gems are used.
+ # You can specify versions of gems by using a hash assignment:
+ # config.gems["rails"] = "2.0.2"
+
+ # You can also use regexps or Gem::Dependency objects for flexibility or
+ # fine-grained control.
+ # config.gems << /^merb-/
+ # config.gems << Gem::Dependency.new("merb-core", "= 0.9.3")
+
+ # Include gem dependencies not mentioned specifically
+ config.gem_dependencies = true
+
+ # Files to be included in the root of the webapp. Note that files in public
+ # will have the leading 'public/' part of the path stripped during staging.
+ # config.public_html = FileList["public/**/*", "doc/**/*"]
+
+ # Pathmaps for controlling how public HTML files are copied into the .war
+ # config.pathmaps.public_html = ["%{public/,}p"]
+
+ # Name of the war file (without the .war) -- defaults to the basename
+ # of RAILS_ROOT
+ config.war_name = "test"
+
+ # Name of the MANIFEST.MF template for the war file. Defaults to the
+ # MANIFEST.MF normally generated by `jar cf`.
+ # config.manifest_file = "config/MANIFEST.MF"
+
+ # Value of RAILS_ENV for the webapp -- default as shown below
+ # config.webxml.rails.env = ENV['RAILS_ENV'] || 'production'
+
+ # Application booter to use, one of :rack, :rails, or :merb. (Default :rails)
+ # config.webxml.booter = :rack
+ config.webxml.booter = :rack
+
+ # When using the :rack booter, "Rackup" script to use.
+ # The script is evaluated in a Rack::Builder to load the application.
+ # Examples:
+ # config.webxml.rackup = %{require './lib/demo'; run Rack::Adapter::Camping.new(Demo)}
+ # config.webxml.rackup = require 'cgi' && CGI::escapeHTML(File.read("config.ru"))
+
+ # Control the pool of Rails runtimes. Leaving unspecified means
+ # the pool will grow as needed to service requests. It is recommended
+ # that you fix these values when running a production server!
+ # config.webxml.jruby.min.runtimes = 2
+ # config.webxml.jruby.max.runtimes = 4
+ config.webxml.jruby.min.runtimes = 1
+ config.webxml.jruby.max.runtimes = 1
+ config.webxml.jruby.init.serial = true
+
+ # JNDI data source name
+ # config.webxml.jndi = 'jdbc/rails'
+ config.java_libs = []
+end
+
View
BIN  lib/appengine-api-1.0-sdk-1.2.0.jar
Binary file not shown
View
BIN  lib/jruby-core.jar
Binary file not shown
View
BIN  lib/jruby-rack-0.9.4.jar
Binary file not shown
View
BIN  lib/ruby-stdlib.jar
Binary file not shown
View
24 lib/split-jruby.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+rm -rf jruby-core.jar
+rm -rf ruby-stdlib.jar
+rm -rf tmp_unpack
+mkdir tmp_unpack
+cd tmp_unpack
+jar xf ../jruby-complete.jar
+cd ..
+mkdir jruby-core
+mv tmp_unpack/org jruby-core/
+mv tmp_unpack/com jruby-core/
+mv tmp_unpack/jline jruby-core/
+mv tmp_unpack/jay jruby-core/
+mv tmp_unpack/jruby jruby-core/
+cd jruby-core
+jar cf ../jruby-core.jar .
+cd ../tmp_unpack
+jar cf ../ruby-stdlib.jar .
+cd ..
+rm -rf jruby-core
+rm -rf tmp_unpack
+rm -rf jruby-complete.jar
+
View
BIN  test.war
Binary file not shown
View
10 tmp/war/WEB-INF/app.rb
@@ -0,0 +1,10 @@
+require 'rubygems'
+require 'sinatra'
+require 'pipe'
+
+get '/' do
+ Pipe.create do
+ feed "http://www.reddit.com/r/programming/.rss", :title => /clojure/i
+ end
+end
+
View
22 tmp/war/WEB-INF/appengine-web.xml
@@ -0,0 +1,22 @@
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+ <application>peyepr</application>
+ <version>1</version>
+ <static-files />
+ <resource-files />
+ <sessions-enabled>false</sessions-enabled>
+ <system-properties>
+ <property name="jruby.management.enabled" value="false" />
+ <property name="os.arch" value="" />
+ <property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
+ <property name="jruby.compile.fastest" value="true"/>
+ <property name="jruby.compile.frameless" value="true"/>
+ <property name="jruby.compile.positionless" value="true"/>
+ <property name="jruby.compile.threadless" value="false"/>
+ <property name="jruby.compile.fastops" value="false"/>
+ <property name="jruby.compile.fastcase" value="false"/>
+ <property name="jruby.compile.chainsize" value="500"/>
+ <property name="jruby.compile.lazyHandles" value="false"/>
+ <property name="jruby.compile.peephole" value="true"/>
+ </system-properties>
+</appengine-web-app>
+
View
14 tmp/war/WEB-INF/config.ru
@@ -0,0 +1,14 @@
+require 'rubygems'
+require 'sinatra'
+
+root_dir = File.dirname(__FILE__)
+
+set :environment, :production
+set :root, root_dir
+set :app_file, File.join(root_dir, 'app.rb')
+disable :run
+
+require 'app'
+
+run Sinatra::Application
+
View
62 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/CHANGELOG
@@ -0,0 +1,62 @@
+= 0.6
+=== 15th June, 2007
+* Hpricot for JRuby -- nice work Ola Bini!
+* Inline Markaby for Hpricot documents.
+* XML tags and attributes are no longer downcased like HTML is.
+* new syntax for grabbing everything between two elements using a Range in the search method: (doc/("font".."font/br")) or in nodes_at like so: (doc/"font").nodes_at("*".."br"). Only works with either a pair of siblings or a set of a parent and a sibling.
+* Ignore self-closing endings on tags (such as form) which are containers. Treat them like open parent tags. Reported by Jonathan Nichols on the hpricot list.
+* Escaping of attributes, yanked from Jim Weirich and Sam Ruby's work in Builder.
+* Element#raw_attributes gives unescaped data. Element#attributes gives escaped.
+* Added: Elements#attr, Elements#remove_attr, Elements#remove_class.
+* Added: Traverse#preceding, Traverse#following, Traverse#previous, Traverse#next.
+
+= 0.5
+=== 31rd January, 2007
+
+* support for a[text()="Click Me!"] and h3[text()*="space"] and the like.
+* Hpricot.buffer_size accessor for increasing Hpricot's buffer if you're encountering huge ASP.NET viewstate attribs.
+* some support for colons in tag names (not full namespace support yet.)
+* Element.to_original_html will attempt to preserve the original HTML while merging your changes.
+* Element.to_plain_text converts an element's contents to a simple text format.
+* Element.inner_text removes all tags and returns text nodes concatenated into a single string.
+* no @raw_string variable kept for comments, text, and cdata -- as it's redundant.
+* xpath-style indices (//p/a[1]) but keep in mind that they aren't zero-based.
+* node_position is the index among all sibling nodes, while position is the position among children of identical type.
+* comment() and text() search criteria, like: //p/text(), which selects all text inside paragraph tags.
+* every element has css_path and xpath methods which return respective absolute paths.
+* more flexibility all around: in parsing attributes, tags, comments and cdata.
+
+= 0.4
+=== 11th August, 2006
+
+* The :fixup_tags option will try to sort out the hierarchy so elements end up with the right parents.
+* Elements such as *script* and *style* (identified as having CDATA contents) receive a single text node as their children now. Previously, Hpricot was parsing out tags found in scripts.
+* Better scanning of partially quoted attributes (found by Brent Beardsly on http://uswebgen.com/)
+* Better scanning of unquoted attributes -- thanks to Aaron Patterson for the test cases!
+* Some tags were being output in the empty tag style, although browsers hated that. FIXED!
+* Added Elements#at for finding single elements.
+* Added Elem::Trav#[] and Elem::Trav#[]= for reading and writing attributes.
+
+= 0.3
+=== 7th July, 2006
+
+* Fixed negative string size error on empty tokens. (news.bbc.co.uk)
+* Allow the parser to accept just text nodes. (such as: <tt>Hpricot.parse('TEXT')</tt>)
+* from JQuery to Hpricot::Elements: remove, empty, append, prepend, before, after, wrap, set,
+ html(...), to_html, to_s.
+* on containers: to_html, replace_child, insert_before, insert_after, innerHTML=.
+* Hpricot(...) is an alias for parse.
+* open up all properties to setters, let people do as they may.
+* use to_html for the full html of a node or set of elements.
+* doctypes were messed.
+
+= 0.2
+=== 4th July, 2006
+
+* Rewrote the HTree parser to be simpler, more adequate for the common man. Will add encoding back in later.
+
+= 0.1
+=== 3rd July, 2006
+
+* For whatever reason, wrote this HTML parser in C.
+ I guess Ragel is addictive and I want to improve HTree.
View
18 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/COPYING
@@ -0,0 +1,18 @@
+Copyright (c) 2006 why the lucky stiff
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
284 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/README
@@ -0,0 +1,284 @@
+= Hpricot, Read Any HTML
+
+Hpricot is a fast, flexible HTML parser written in C. It's designed to be very
+accommodating (like Tanaka Akira's HTree) and to have a very helpful library
+(like some JavaScript libs -- JQuery, Prototype -- give you.) The XPath and CSS
+parser, in fact, is based on John Resig's JQuery.
+
+Also, Hpricot can be handy for reading broken XML files, since many of the same
+techniques can be used. If a quote is missing, Hpricot tries to figure it out.
+If tags overlap, Hpricot works on sorting them out. You know, that sort of
+thing.
+
+*Please read this entire document* before making assumptions about how this
+software works.
+
+== An Overview
+
+Let's clear up what Hpricot is.
+
+# Hpricot is *a standalone library*. It requires no other libraries. Just Ruby!
+# While priding itself on speed, Hpricot *works hard to sort out bad HTML* and
+ pays a small penalty in order to get that right. So that's slightly more important
+ to me than speed.
+# *If you can see it in Firefox, then Hpricot should parse it.* That's
+ how it should be! Let me know the minute it's otherwise.
+# Primarily, Hpricot is used for reading HTML and tries to sort out troubled
+ HTML by having some idea of what good HTML is. Some people still like to use
+ Hpricot for XML reading, but *remember to use the Hpricot::XML() method* for that!
+
+== The Hpricot Kingdom
+
+First, here are all the links you need to know:
+
+* http://code.whytheluckystiff.net/hpricot is the Hpricot wiki and bug tracker.
+ Go there for news and recipes and patches. It's the center of activity.
+* http://code.whytheluckystiff.net/svn/hpricot/trunk is the main Subversion
+ repository for Hpricot. You can get the latest code there.
+* http://code.whytheluckystiff.net/doc/hpricot is the home for the latest copy of
+ this reference.
+* See COPYING for the terms of this software. (Spoiler: it's absolutely free.)
+
+If you have any trouble, don't hesitate to contact the author. As always, I'm
+not going to say "Use at your own risk" because I don't want this library to be
+risky. If you trip on something, I'll share the liability by repairing things
+as quickly as I can. Your responsibility is to report the inadequacies.
+
+== Installing Hpricot
+
+You may get the latest stable version from Rubyforge. Win32 binaries and source
+gems are available.
+
+ $ gem install hpricot
+
+As Hpricot is still under active development, you can also try the most recent
+candidate build here:
+
+ $ gem install hpricot --source http://code.whytheluckystiff.net
+
+The development gem is usually in pretty good shape actually. You can also
+get the bleeding edge code or plain Ruby tarballs on the wiki.
+
+== An Hpricot Showcase
+
+We're going to run through a big pile of examples to get you jump-started.
+Many of these examples are also found at
+http://code.whytheluckystiff.net/hpricot/wiki/HpricotBasics, in case you
+want to add some of your own.
+
+=== Loading Hpricot Itself
+
+You have probably got the gem, right? To load Hpricot:
+
+ require 'rubygems'
+ require 'hpricot'
+
+If you've installed the plain source distribution, go ahead and just:
+
+ require 'hpricot'
+
+=== Load an HTML Page
+
+The <tt>Hpricot()</tt> method takes a string or any IO object and loads the
+contents into a document object.
+
+ doc = Hpricot("<p>A simple <b>test</b> string.</p>")
+
+To load from a file, just get the stream open:
+
+ doc = open("index.html") { |f| Hpricot(f) }
+
+To load from a web URL, use <tt>open-uri</tt>, which comes with Ruby:
+
+ require 'open-uri'
+ doc = open("http://qwantz.com/") { |f| Hpricot(f) }
+
+Hpricot uses an internal buffer to parse the file, so the IO will stream
+properly and large documents won't be loaded into memory all at once. However,
+the parsed document object will be present in memory, in its entirety.
+
+=== Search for Elements
+
+Use <tt>Doc.search</tt>:
+
+ doc.search("//p[@class='posted']")
+ #=> #<Hpricot:Elements[{p ...}, {p ...}]>
+
+<tt>Doc.search</tt> can take an XPath or CSS expression. In the above example,
+all paragraph <tt><p></tt> elements are grabbed which have a <tt>class</tt>
+attribute of <tt>"posted"</tt>.
+
+A shortcut is to use the divisor:
+
+ (doc/"p.posted")
+ #=> #<Hpricot:Elements[{p ...}, {p ...}]>
+
+=== Finding Just One Element
+
+If you're looking for a single element, the <tt>at</tt> method will return the
+first element matched by the expression. In this case, you'll get back the
+element itself rather than the <tt>Hpricot::Elements</tt> array.
+
+ doc.at("body")['onload']
+
+The above code will find the body tag and give you back the <tt>onload</tt>
+attribute. This is the most common reason to use the element directly: when
+reading and writing HTML attributes.
+
+=== Fetching the Contents of an Element
+
+Just as with browser scripting, the <tt>inner_html</tt> property can be used to
+get the inner contents of an element.
+
+ (doc/"#elementID").inner_html
+ #=> "..<b>contents</b>.."
+
+If your expression matches more than one element, you'll get back the contents
+of ''all the matched elements''. So you may want to use <tt>first</tt> to be
+sure you get back only one.
+
+ (doc/"#elementID").first.inner_html
+ #=> "..<b>contents</b>.."
+
+=== Fetching the HTML for an Element
+
+If you want the HTML for the whole element (not just the contents), use
+<tt>to_html</tt>:
+
+ (doc/"#elementID").to_html
+ #=> "<div id='elementID'>...</div>"
+
+=== Looping
+
+All searches return a set of <tt>Hpricot::Elements</tt>. Go ahead and loop
+through them like you would an array.
+
+ (doc/"p/a/img").each do |img|
+ puts img.attributes['class']
+ end
+
+=== Continuing Searches
+
+Searches can be continued from a collection of elements, in order to search deeper.
+
+ # find all paragraphs.
+ elements = doc.search("/html/body//p")
+ # continue the search by finding any images within those paragraphs.
+ (elements/"img")
+ #=> #<Hpricot::Elements[{img ...}, {img ...}]>
+
+Searches can also be continued by searching within container elements.
+
+ # find all images within paragraphs.
+ doc.search("/html/body//p").each do |para|
+ puts "== Found a paragraph =="
+ pp para
+
+ imgs = para.search("img")
+ if imgs.any?
+ puts "== Found #{imgs.length} images inside =="
+ end
+ end
+
+Of course, the most succinct ways to do the above are using CSS or XPath.
+
+ # the xpath version
+ (doc/"/html/body//p//img")
+ # the css version
+ (doc/"html > body > p img")
+ # ..or symbols work, too!
+ (doc/:html/:body/:p/:img)
+
+=== Looping Edits
+
+You may certainly edit objects from within your search loops. Then, when you
+spit out the HTML, the altered elements will show.
+
+ (doc/"span.entryPermalink").each do |span|
+ span.attributes['class'] = 'newLinks'
+ end
+ puts doc
+
+This changes all <tt>span.entryPermalink</tt> elements to
+<tt>span.newLinks</tt>. Keep in mind that there are often more convenient ways
+of doing this. Such as the <tt>set</tt> method:
+
+ (doc/"span.entryPermalink").set(:class => 'newLinks')
+
+=== Figuring Out Paths
+
+Every element can tell you its unique path (either XPath or CSS) to get to the
+element from the root tag.
+
+The <tt>css_path</tt> method:
+
+ doc.at("div > div:nth(1)").css_path
+ #=> "div > div:nth(1)"
+ doc.at("#header").css_path
+ #=> "#header"
+
+Or, the <tt>xpath</tt> method:
+
+ doc.at("div > div:nth(1)").xpath
+ #=> "/div/div:eq(1)"
+ doc.at("#header").xpath
+ #=> "//div[@id='header']"
+
+== Hpricot Fixups
+
+When loading HTML documents, you have a few settings that can make Hpricot more
+or less intense about how it gets involved.
+
+== :fixup_tags
+
+Really, there are so many ways to clean up HTML and your intentions may be to
+keep the HTML as-is. So Hpricot's default behavior is to keep things flexible.
+Making sure to open and close all the tags, but ignore any validation problems.
+
+As of Hpricot 0.4, there's a new <tt>:fixup_tags</tt> option which will attempt
+to shift the document's tags to meet XHTML 1.0 Strict.
+
+ doc = open("index.html") { |f| Hpricot f, :fixup_tags => true }
+
+This doesn't quite meet the XHTML 1.0 Strict standard, it just tries to follow
+the rules a bit better. Like: say Hpricot finds a paragraph in a link, it's
+going to move the paragraph below the link. Or up and out of other elements
+where paragraphs don't belong.
+
+If an unknown element is found, it is ignored. Again, <tt>:fixup_tags</tt>.
+
+== :xhtml_strict
+
+So, let's go beyond just trying to fix the hierarchy. The
+<tt>:xhtml_strict</tt> option really tries to force the document to be an XHTML
+1.0 Strict document. Even at the cost of removing elements that get in the way.
+
+ doc = open("index.html") { |f| Hpricot f, :xhtml_strict => true }
+
+What measures does <tt>:xhtml_strict</tt> take?
+
+ 1. Shift elements into their proper containers just like :fixup_tags.
+ 2. Remove unknown elements.
+ 3. Remove unknown attributes.
+ 4. Remove illegal content.
+ 5. Alter the doctype to XHTML 1.0 Strict.
+
+== Hpricot.XML()
+
+The last option is the <tt>:xml</tt> option, which makes some slight variations
+on the standard mode. The main difference is that :xml mode won't try to output
+tags which are friendlier for browsers. For example, if an opening and closing
+<tt>br</tt> tag is found, XML mode won't try to turn that into an empty element.
+
+XML mode also doesn't downcase the tags and attributes for you. So pay attention
+to case, friends.
+
+The primary way to use Hpricot's XML mode is to call the Hpricot.XML method:
+
+ doc = open("http://redhanded.hobix.com/index.xml") do |f|
+ Hpricot.XML(f)
+ end
+
+*Also, :fixup_tags is canceled out by the :xml option.* This is because
+:fixup_tags makes assumptions based how HTML is structured. Specifically, how
+tags are defined in the XHTML 1.0 DTD.
View
262 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/Rakefile
@@ -0,0 +1,262 @@
+require 'rake'
+require 'rake/clean'
+require 'rake/gempackagetask'
+require 'rake/rdoctask'
+require 'rake/testtask'
+require 'fileutils'
+include FileUtils
+
+RbConfig = Config unless defined?(RbConfig)
+
+NAME = "hpricot"
+REV = (`#{ENV['GIT'] || "git"} rev-list HEAD`.split.length + 1).to_s
+VERS = ENV['VERSION'] || "0.6" + (REV ? ".#{REV}" : "")
+PKG = "#{NAME}-#{VERS}"
+BIN = "*.{bundle,jar,so,obj,pdb,lib,def,exp,class}"
+ARCHLIB = "lib/#{::Config::CONFIG['arch']}"
+CLEAN.include ["ext/hpricot_scan/#{BIN}", "ext/fast_xs/#{BIN}", "lib/**/#{BIN}", ARCHLIB,
+ 'ext/fast_xs/Makefile', 'ext/hpricot_scan/Makefile',
+ '**/.*.sw?', '*.gem', '.config', 'pkg']
+RDOC_OPTS = ['--quiet', '--title', 'The Hpricot Reference', '--main', 'README', '--inline-source']
+PKG_FILES = %w(CHANGELOG COPYING README Rakefile) +
+ Dir.glob("{bin,doc,test,lib,extras}/**/*") +
+ Dir.glob("ext/**/*.{h,java,c,rb,rl}") +
+ %w[ext/hpricot_scan/hpricot_scan.c ext/hpricot_scan/HpricotScanService.java] # needed because they are generated later
+RAGEL_C_CODE_GENERATION_STYLES = {
+ "table_driven" => 'T0',
+ "faster_table_driven" => 'T1',
+ "flat_table_driven" => 'F0',
+ "faster_flat_table_driven" => 'F1',
+ "goto_driven" => 'G0',
+ "faster_goto_driven" => 'G1',
+ "really_fast goto_driven" => 'G2'
+ # "n_way_split_really_fast_goto_driven" => 'P<N>'
+}
+DEFAULT_RAGEL_C_CODE_GENERATION = "really_fast goto_driven"
+SPEC =
+ Gem::Specification.new do |s|
+ s.name = NAME
+ s.version = VERS
+ s.platform = Gem::Platform::RUBY
+ s.has_rdoc = true
+ s.rdoc_options += RDOC_OPTS
+ s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"]
+ s.summary = "a swift, liberal HTML parser with a fantastic library"
+ s.description = s.summary
+ s.author = "why the lucky stiff"
+ s.email = 'why@ruby-lang.org'
+ s.homepage = 'http://code.whytheluckystiff.net/hpricot/'
+ s.files = PKG_FILES
+ s.require_paths = [ARCHLIB, "lib"]
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
+ s.bindir = "bin"
+ end
+
+desc "Does a full compile, test run"
+task :default => [:compile, :test]
+
+desc "Packages up Hpricot."
+task :package => [:clean, :ragel]
+
+desc "Releases packages for all Hpricot packages and platforms."
+task :release => [:package, :package_win32, :package_jruby]
+
+desc "Run all the tests"
+Rake::TestTask.new do |t|
+ t.libs << "test" << ARCHLIB
+ t.test_files = FileList['test/test_*.rb']
+ t.verbose = true
+end
+
+Rake::RDocTask.new do |rdoc|
+ rdoc.rdoc_dir = 'doc/rdoc'
+ rdoc.options += RDOC_OPTS
+ rdoc.main = "README"
+ rdoc.rdoc_files.add ['README', 'CHANGELOG', 'COPYING', 'lib/**/*.rb']
+end
+
+Rake::GemPackageTask.new(SPEC) do |p|
+ p.need_tar = true
+ p.gem_spec = SPEC
+end
+
+['hpricot_scan', 'fast_xs'].each do |extension|
+ ext = "ext/#{extension}"
+ ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
+ ext_files = FileList[
+ "#{ext}/*.c",
+ "#{ext}/*.h",
+ "#{ext}/*.rl",
+ "#{ext}/extconf.rb",
+ "#{ext}/Makefile",
+ "lib"
+ ]
+
+ desc "Builds just the #{extension} extension"
+ task extension.to_sym => ["#{ext}/Makefile", ext_so ]
+
+ file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
+ Dir.chdir(ext) do ruby "extconf.rb" end
+ end
+
+ file ext_so => ext_files do
+ Dir.chdir(ext) do
+ sh(RUBY_PLATFORM =~ /win32/ ? 'nmake' : 'make')
+ end
+ mkdir_p ARCHLIB
+ cp ext_so, ARCHLIB
+ end
+end
+
+task "lib" do
+ directory "lib"
+end
+
+desc "Compiles the Ruby extension"
+task :compile => [:hpricot_scan, :fast_xs] do
+ if Dir.glob(File.join(ARCHLIB,"hpricot_scan.*")).length == 0
+ STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+ STDERR.puts "Gem actually failed to build. Your system is"
+ STDERR.puts "NOT configured properly to build hpricot."
+ STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+ exit(1)
+ end
+end
+task :hpricot_scan => [:ragel]
+
+desc "Determines the Ragel version and displays it on the console along with the location of the Ragel binary."
+task :ragel_version do
+ @ragel_v = `ragel -v`[/(version )(\S*)/,2].to_f
+ puts "Using ragel version: #{@ragel_v}, location: #{`which ragel`}"
+ @ragel_v
+end
+
+desc "Generates the C scanner code with Ragel."
+task :ragel => [:ragel_version] do
+ if @ragel_v >= 6.1
+ @ragel_c_code_generation_style = RAGEL_C_CODE_GENERATION_STYLES[DEFAULT_RAGEL_C_CODE_GENERATION]
+ sh %{cd ext/hpricot_scan; ragel hpricot_scan.rl -#{@ragel_c_code_generation_style} -o hpricot_scan.c}
+ else
+ STDERR.puts "Ragel 6.1 or greater is required."
+ exit(1)
+ end
+end
+
+# Java only supports the table-driven code
+# generation style at this point.
+desc "Generates the Java scanner code using the Ragel table-driven code generation style."
+task :ragel_java => [:ragel_version] do
+ if @ragel_v >= 6.1
+ puts "compiling with ragel version #{@ragel_v}"
+ sh %{ragel -J -o ext/hpricot_scan/HpricotScanService.java ext/hpricot_scan/hpricot_scan.java.rl}
+ else
+ STDERR.puts "Ragel 6.1 or greater is required."
+ exit(1)
+ end
+end
+
+### Win32 Packages ###
+
+Win32Spec = SPEC.dup
+Win32Spec.platform = Gem::Platform::CURRENT
+Win32Spec.files = PKG_FILES + ["#{ARCHLIB}/hpricot_scan.so", "#{ARCHLIB}/fast_xs.so"]
+Win32Spec.extensions = []
+
+WIN32_PKG_DIR = "#{PKG}-mswin32"
+
+desc "Package up the Win32 distribution."
+file WIN32_PKG_DIR => [:package] do
+ sh "tar zxf pkg/#{PKG}.tgz"
+ mv PKG, WIN32_PKG_DIR
+end
+
+desc "Cross-compile the hpricot_scan extension for win32"
+file "hpricot_scan_win32" => [WIN32_PKG_DIR] do
+ cp "extras/mingw-rbconfig.rb", "#{WIN32_PKG_DIR}/ext/hpricot_scan/rbconfig.rb"
+ sh "cd #{WIN32_PKG_DIR}/ext/hpricot_scan/ && ruby -I. extconf.rb && make"
+ mv "#{WIN32_PKG_DIR}/ext/hpricot_scan/hpricot_scan.so", "#{WIN32_PKG_DIR}/#{ARCHLIB}"
+end
+
+desc "Build the binary RubyGems package for win32"
+task :package_win32 => ["hpricot_scan_win32"] do
+ Dir.chdir("#{WIN32_PKG_DIR}") do
+ Gem::Builder.new(Win32Spec).build
+ verbose(true) {
+ mv Dir["*.gem"].first, "../pkg/#{WIN32_PKG_DIR}.gem"
+ }
+ end
+end
+
+CLEAN.include WIN32_PKG_DIR
+
+### JRuby Packages ###
+
+def java_classpath_arg
+ # A myriad of ways to discover the JRuby classpath
+ classpath = begin
+ require 'java'
+ # Already running in a JRuby JVM
+ Java::java.lang.System.getProperty('java.class.path')
+ rescue LoadError
+ ENV['JRUBY_PARENT_CLASSPATH'] || ENV['JRUBY_HOME'] && FileList["#{ENV['JRUBY_HOME']}/lib/*.jar"].join(File::PATH_SEPARATOR)
+ end
+ classpath ? "-cp #{classpath}" : ""
+end
+
+def compile_java(filename, jarname)
+ sh %{javac -source 1.4 -target 1.4 #{java_classpath_arg} #{filename}}
+ sh %{jar cf #{jarname} *.class}
+end
+
+task :hpricot_scan_java => [:ragel_java] do
+ Dir.chdir "ext/hpricot_scan" do
+ compile_java("HpricotScanService.java", "hpricot_scan.jar")
+ end
+end
+
+task :fast_xs_java do
+ Dir.chdir "ext/fast_xs" do
+ compile_java("FastXsService.java", "fast_xs.jar")
+ end
+end
+
+desc "Compiles the JRuby extensions"
+task :hpricot_java => [:hpricot_scan_java, :fast_xs_java] do
+ mkdir_p "#{ARCHLIB}"
+ %w(hpricot_scan fast_xs).each {|ext| mv "ext/#{ext}/#{ext}.jar", "#{ARCHLIB}"}
+end
+
+JRubySpec = SPEC.dup
+JRubySpec.platform = 'jruby'
+JRubySpec.files = PKG_FILES + ["#{ARCHLIB}/hpricot_scan.jar", "#{ARCHLIB}/fast_xs.jar"]
+JRubySpec.extensions = []
+
+JRUBY_PKG_DIR = "#{PKG}-jruby"
+
+desc "Package up the JRuby distribution."
+file JRUBY_PKG_DIR => [:ragel_java, :package] do
+ sh "tar zxf pkg/#{PKG}.tgz"
+ mv PKG, JRUBY_PKG_DIR
+end
+
+desc "Build the RubyGems package for JRuby"
+task :package_jruby => JRUBY_PKG_DIR do
+ Dir.chdir("#{JRUBY_PKG_DIR}") do
+ Rake::Task[:hpricot_java].invoke
+ Gem::Builder.new(JRubySpec).build
+ verbose(true) {
+ mv Dir["*.gem"].first, "../pkg/#{JRUBY_PKG_DIR}.gem"
+ }
+ end
+end
+
+CLEAN.include JRUBY_PKG_DIR
+
+task :install do
+ sh %{rake package}
+ sh %{sudo gem install pkg/#{NAME}-#{VERS}}
+end
+
+task :uninstall => [:clean] do
+ sh %{sudo gem uninstall #{NAME}}
+end
View
1,018 tmp/war/WEB-INF/gems/gems/hpricot-0.6.164-java/ext/fast_xs/FastXsService.java
@@ -0,0 +1,1018 @@
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import org.jruby.Ruby;
+import org.jruby.RubyModule;
+import org.jruby.runtime.CallbackFactory;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.load.BasicLibraryService;
+import org.jruby.util.collections.IntHashMap;
+
+public class FastXsService implements BasicLibraryService {
+
+ public boolean basicLoad(final Ruby runtime) throws IOException {
+ RubyModule string = runtime.getModule("String");
+ CallbackFactory fact = runtime.callbackFactory(FastXsService.class);
+ string.defineMethod("fast_xs",fact.getFastSingletonMethod("fast_xs"));
+ return true;
+ }
+
+ public static IRubyObject fast_xs(IRubyObject recv) {
+ String string = recv.convertToString().getUnicodeValue();
+ StringWriter writer = new StringWriter ((int)(string.length() * 1.5));
+ try {
+ Entities.XML.escape(writer, string);
+ return recv.getRuntime().newString(writer.toString());
+ } catch (IOException e) {
+ throw recv.getRuntime().newIOErrorFromException(e);
+ }
+ }
+}
+
+// From Apache commons-lang,
+// http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/Entities.java?revision=560660&view=markup
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <p>
+ * Provides HTML and XML entity utilities.
+ * </p>
+ *
+ * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
+ * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
+ * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
+ * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
+ * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
+ *
+ * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
+ * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
+ * @since 2.0
+ * @version $Id$
+ */
+class Entities {
+
+ private static final String[][] BASIC_ARRAY = {{"quot", "34"}, // " - double-quote
+ {"amp", "38"}, // & - ampersand
+ {"lt", "60"}, // < - less-than
+ {"gt", "62"}, // > - greater-than
+ };
+
+ private static final String[][] APOS_ARRAY = {{"apos", "39"}, // XML apostrophe
+ };
+
+ // package scoped for testing
+ static final String[][] ISO8859_1_ARRAY = {{"nbsp", "160"}, // non-breaking space
+ {"iexcl", "161"}, // inverted exclamation mark
+ {"cent", "162"}, // cent sign
+ {"pound", "163"}, // pound sign
+ {"curren", "164"}, // currency sign
+ {"yen", "165"}, // yen sign = yuan sign
+ {"brvbar", "166"}, // broken bar = broken vertical bar
+ {"sect", "167"}, // section sign
+ {"uml", "168"}, // diaeresis = spacing diaeresis
+ {"copy", "169"}, // © - copyright sign
+ {"ordf", "170"}, // feminine ordinal indicator
+ {"laquo", "171"}, // left-pointing double angle quotation mark = left pointing guillemet
+ {"not", "172"}, // not sign
+ {"shy", "173"}, // soft hyphen = discretionary hyphen
+ {"reg", "174"}, // ® - registered trademark sign
+ {"macr", "175"}, // macron = spacing macron = overline = APL overbar
+ {"deg", "176"}, // degree sign
+ {"plusmn", "177"}, // plus-minus sign = plus-or-minus sign
+ {"sup2", "178"}, // superscript two = superscript digit two = squared
+ {"sup3", "179"}, // superscript three = superscript digit three = cubed
+ {"acute", "180"}, // acute accent = spacing acute
+ {"micro", "181"}, // micro sign
+ {"para", "182"}, // pilcrow sign = paragraph sign
+ {"middot", "183"}, // middle dot = Georgian comma = Greek middle dot
+ {"cedil", "184"}, // cedilla = spacing cedilla
+ {"sup1", "185"}, // superscript one = superscript digit one
+ {"ordm", "186"}, // masculine ordinal indicator
+ {"raquo", "187"}, // right-pointing double angle quotation mark = right pointing guillemet
+ {"frac14", "188"}, // vulgar fraction one quarter = fraction one quarter
+ {"frac12", "189"}, // vulgar fraction one half = fraction one half
+ {"frac34", "190"}, // vulgar fraction three quarters = fraction three quarters
+ {"iquest", "191"}, // inverted question mark = turned question mark
+ {"Agrave", "192"}, // À - uppercase A, grave accent
+ {"Aacute", "193"}, // Á - uppercase A, acute accent
+ {"Acirc", "194"}, // Â - uppercase A, circumflex accent
+ {"Atilde", "195"}, // Ã - uppercase A, tilde
+ {"Auml", "196"}, // Ä - uppercase A, umlaut
+ {"Aring", "197"}, // Å - uppercase A, ring
+ {"AElig", "198"}, // Æ - uppercase AE
+ {"Ccedil", "199"}, // Ç - uppercase C, cedilla
+ {"Egrave", "200"}, // È - uppercase E, grave accent
+ {"Eacute", "201"}, // É - uppercase E, acute accent
+ {"Ecirc", "202"}, // Ê - uppercase E, circumflex accent
+ {"Euml", "203"}, // Ë - uppercase E, umlaut
+ {"Igrave", "204"}, // Ì - uppercase I, grave accent
+ {"Iacute", "205"}, // Í - uppercase I, acute accent
+ {"Icirc", "206"}, // Î - uppercase I, circumflex accent
+ {"Iuml", "207"}, // Ï - uppercase I, umlaut
+ {"ETH", "208"}, // Ð - uppercase Eth, Icelandic
+ {"Ntilde", "209"}, // Ñ - uppercase N, tilde
+ {"Ograve", "210"}, // Ò - uppercase O, grave accent
+ {"Oacute", "211"}, // Ó - uppercase O, acute accent
+ {"Ocirc", "212"}, // Ô - uppercase O, circumflex accent
+ {"Otilde", "213"}, // Õ - uppercase O, tilde
+ {"Ouml", "214"}, // Ö - uppercase O, umlaut
+ {"times", "215"}, // multiplication sign
+ {"Oslash", "216"}, // Ø - uppercase O, slash
+ {"Ugrave", "217"}, // Ù - uppercase U, grave accent
+ {"Uacute", "218"}, // Ú - uppercase U, acute accent
+ {"Ucirc", "219"}, // Û - uppercase U, circumflex accent
+ {"Uuml", "220"}, // Ü - uppercase U, umlaut
+ {"Yacute", "221"}, // Ý - uppercase Y, acute accent
+ {"THORN", "222"}, // Þ - uppercase THORN, Icelandic
+ {"szlig", "223"}, // ß - lowercase sharps, German
+ {"agrave", "224"}, // à - lowercase a, grave accent
+ {"aacute", "225"}, // á - lowercase a, acute accent
+ {"acirc", "226"}, // â - lowercase a, circumflex accent
+ {"atilde", "227"}, // ã - lowercase a, tilde
+ {"auml", "228"}, // ä - lowercase a, umlaut
+ {"aring", "229"}, // å - lowercase a, ring
+ {"aelig", "230"}, // æ - lowercase ae
+ {"ccedil", "231"}, // ç - lowercase c, cedilla
+ {"egrave", "232"}, // è - lowercase e, grave accent
+ {"eacute", "233"}, // é - lowercase e, acute accent
+ {"ecirc", "234"}, // ê - lowercase e, circumflex accent
+ {"euml", "235"}, // ë - lowercase e, umlaut
+ {"igrave", "236"}, // ì - lowercase i, grave accent
+ {"iacute", "237"}, // í - lowercase i, acute accent
+ {"icirc", "238"}, // î - lowercase i, circumflex accent
+ {"iuml", "239"}, // ï - lowercase i, umlaut
+ {"eth", "240"}, // ð - lowercase eth, Icelandic
+ {"ntilde", "241"}, // ñ - lowercase n, tilde
+ {"ograve", "242"}, // ò - lowercase o, grave accent
+ {"oacute", "243"}, // ó - lowercase o, acute accent
+ {"ocirc", "244"}, // ô - lowercase o, circumflex accent
+ {"otilde", "245"}, // õ - lowercase o, tilde
+ {"ouml", "246"}, // ö - lowercase o, umlaut
+ {"divide", "247"}, // division sign
+ {"oslash", "248"}, // ø - lowercase o, slash
+ {"ugrave", "249"}, // ù - lowercase u, grave accent
+ {"uacute", "250"}, // ú - lowercase u, acute accent
+ {"ucirc", "251"}, // û - lowercase u, circumflex accent
+ {"uuml", "252"}, // ü - lowercase u, umlaut
+ {"yacute", "253"}, // ý - lowercase y, acute accent
+ {"thorn", "254"}, // þ - lowercase thorn, Icelandic
+ {"yuml", "255"}, // ÿ - lowercase y, umlaut
+ };
+
+ // http://www.w3.org/TR/REC-html40/sgml/entities.html
+ // package scoped for testing
+ static final String[][] HTML40_ARRAY = {
+ // <!-- Latin Extended-B -->
+ {"fnof", "402"}, // latin small f with hook = function= florin, U+0192 ISOtech -->
+ // <!-- Greek -->
+ {"Alpha", "913"}, // greek capital letter alpha, U+0391 -->
+ {"Beta", "914"}, // greek capital letter beta, U+0392 -->
+ {"Gamma", "915"}, // greek capital letter gamma,U+0393 ISOgrk3 -->
+ {"Delta", "916"}, // greek capital letter delta,U+0394 ISOgrk3 -->
+ {"Epsilon", "917"}, // greek capital letter epsilon, U+0395 -->
+ {"Zeta", "918"}, // greek capital letter zeta, U+0396 -->
+ {"Eta", "919"}, // greek capital letter eta, U+0397 -->
+ {"Theta", "920"}, // greek capital letter theta,U+0398 ISOgrk3 -->
+ {"Iota", "921"}, // greek capital letter iota, U+0399 -->
+ {"Kappa", "922"}, // greek capital letter kappa, U+039A -->
+ {"Lambda", "923"}, // greek capital letter lambda,U+039B ISOgrk3 -->
+ {"Mu", "924"}, // greek capital letter mu, U+039C -->
+ {"Nu", "925"}, // greek capital letter nu, U+039D -->
+ {"Xi", "926"}, // greek capital letter xi, U+039E ISOgrk3 -->
+ {"Omicron", "927"}, // greek capital letter omicron, U+039F -->
+ {"Pi", "928"}, // greek capital letter pi, U+03A0 ISOgrk3 -->
+ {"Rho", "929"}, // greek capital letter rho, U+03A1 -->
+ // <!-- there is no Sigmaf, and no U+03A2 character either -->
+ {"Sigma", "931"}, // greek capital letter sigma,U+03A3 ISOgrk3 -->
+ {"Tau", "932"}, // greek capital letter tau, U+03A4 -->
+ {"Upsilon", "933"}, // greek capital letter upsilon,U+03A5 ISOgrk3 -->
+ {"Phi", "934"}, // greek capital letter phi,U+03A6 ISOgrk3 -->
+ {"Chi", "935"}, // greek capital letter chi, U+03A7 -->
+ {"Psi", "936"}, // greek capital letter psi,U+03A8 ISOgrk3 -->
+ {"Omega", "937"}, // greek capital letter omega,U+03A9 ISOgrk3 -->
+ {"alpha", "945"}, // greek small letter alpha,U+03B1 ISOgrk3 -->
+ {"beta", "946"}, // greek small letter beta, U+03B2 ISOgrk3 -->
+ {"gamma", "947"}, // greek small letter gamma,U+03B3 ISOgrk3 -->
+ {"delta", "948"}, // greek small letter delta,U+03B4 ISOgrk3 -->
+ {"epsilon", "949"}, // greek small letter epsilon,U+03B5 ISOgrk3 -->
+ {"zeta", "950"}, // greek small letter zeta, U+03B6 ISOgrk3 -->
+ {"eta", "951"}, // greek small letter eta, U+03B7 ISOgrk3 -->
+ {"theta", "952"}, // greek small letter theta,U+03B8 ISOgrk3 -->
+ {"iota", "953"}, // greek small letter iota, U+03B9 ISOgrk3 -->
+ {"kappa", "954"}, // greek small letter kappa,U+03BA ISOgrk3 -->
+ {"lambda", "955"}, // greek small letter lambda,U+03BB ISOgrk3 -->
+ {"mu", "956"}, // greek small letter mu, U+03BC ISOgrk3 -->
+ {"nu", "957"}, // greek small letter nu, U+03BD ISOgrk3 -->
+ {"xi", "958"}, // greek small letter xi, U+03BE ISOgrk3 -->
+ {"omicron", "959"}, // greek small letter omicron, U+03BF NEW -->
+ {"pi", "960"}, // greek small letter pi, U+03C0 ISOgrk3 -->
+ {"rho", "961"}, // greek small letter rho, U+03C1 ISOgrk3 -->
+ {"sigmaf", "962"}, // greek small letter final sigma,U+03C2 ISOgrk3 -->
+ {"sigma", "963"}, // greek small letter sigma,U+03C3 ISOgrk3 -->
+ {"tau", "964"}, // greek small letter tau, U+03C4 ISOgrk3 -->
+ {"upsilon", "965"}, // greek small letter upsilon,U+03C5 ISOgrk3 -->
+ {"phi", "966"}, // greek small letter phi, U+03C6 ISOgrk3 -->
+ {"chi", "967"}, // greek small letter chi, U+03C7 ISOgrk3 -->
+ {"psi", "968"}, // greek small letter psi, U+03C8 ISOgrk3 -->
+ {"omega", "969"}, // greek small letter omega,U+03C9 ISOgrk3 -->
+ {"thetasym", "977"}, // greek small letter theta symbol,U+03D1 NEW -->
+ {"upsih", "978"}, // greek upsilon with hook symbol,U+03D2 NEW -->
+ {"piv", "982"}, // greek pi symbol, U+03D6 ISOgrk3 -->
+ // <!-- General Punctuation -->
+ {"bull", "8226"}, // bullet = black small circle,U+2022 ISOpub -->
+ // <!-- bullet is NOT the same as bullet operator, U+2219 -->
+ {"hellip", "8230"}, // horizontal ellipsis = three dot leader,U+2026 ISOpub -->
+ {"prime", "8242"}, // prime = minutes = feet, U+2032 ISOtech -->
+ {"Prime", "8243"}, // double prime = seconds = inches,U+2033 ISOtech -->
+ {"oline", "8254"}, // overline = spacing overscore,U+203E NEW -->
+ {"frasl", "8260"}, // fraction slash, U+2044 NEW -->
+ // <!-- Letterlike Symbols -->
+ {"weierp", "8472"}, // script capital P = power set= Weierstrass p, U+2118 ISOamso -->
+ {"image", "8465"}, // blackletter capital I = imaginary part,U+2111 ISOamso -->
+ {"real", "8476"}, // blackletter capital R = real part symbol,U+211C ISOamso -->
+ {"trade", "8482"}, // trade mark sign, U+2122 ISOnum -->
+ {"alefsym", "8501"}, // alef symbol = first transfinite cardinal,U+2135 NEW -->
+ // <!-- alef symbol is NOT the same as hebrew letter alef,U+05D0 although the
+ // same glyph could be used to depict both characters -->
+ // <!-- Arrows -->
+ {"larr", "8592"}, // leftwards arrow, U+2190 ISOnum -->
+ {"uarr", "8593"}, // upwards arrow, U+2191 ISOnum-->
+ {"rarr", "8594"}, // rightwards arrow, U+2192 ISOnum -->
+ {"darr", "8595"}, // downwards arrow, U+2193 ISOnum -->
+ {"harr", "8596"}, // left right arrow, U+2194 ISOamsa -->
+ {"crarr", "8629"}, // downwards arrow with corner leftwards= carriage return, U+21B5 NEW -->
+ {"lArr", "8656"}, // leftwards double arrow, U+21D0 ISOtech -->
+ // <!-- ISO 10646 does not say that lArr is the same as the 'is implied by'
+ // arrow but also does not have any other character for that function.
+ // So ? lArr canbe used for 'is implied by' as ISOtech suggests -->
+ {"uArr", "8657"}, // upwards double arrow, U+21D1 ISOamsa -->
+ {"rArr", "8658"}, // rightwards double arrow,U+21D2 ISOtech -->
+ // <!-- ISO 10646 does not say this is the 'implies' character but does not
+ // have another character with this function so ?rArr can be used for
+ // 'implies' as ISOtech suggests -->
+ {"dArr", "8659"}, // downwards double arrow, U+21D3 ISOamsa -->
+ {"hArr", "8660"}, // left right double arrow,U+21D4 ISOamsa -->
+ // <!-- Mathematical Operators -->
+ {"forall", "8704"}, // for all, U+2200 ISOtech -->
+ {"part", "8706"}, // partial differential, U+2202 ISOtech -->
+ {"exist", "8707"}, // there exists, U+2203 ISOtech -->
+ {"empty", "8709"}, // empty set = null set = diameter,U+2205 ISOamso -->
+ {"nabla", "8711"}, // nabla = backward difference,U+2207 ISOtech -->
+ {"isin", "8712"}, // element of, U+2208 ISOtech -->
+ {"notin", "8713"}, // not an element of, U+2209 ISOtech -->
+ {"ni", "8715"}, // contains as member, U+220B ISOtech -->
+ // <!-- should there be a more memorable name than 'ni'? -->
+ {"prod", "8719"}, // n-ary product = product sign,U+220F ISOamsb -->
+ // <!-- prod is NOT the same character as U+03A0 'greek capital letter pi'
+ // though the same glyph might be used for both -->
+ {"sum", "8721"}, // n-ary summation, U+2211 ISOamsb -->
+ // <!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
+ // though the same glyph might be used for both -->
+ {"minus", "8722"}, // minus sign, U+2212 ISOtech -->
+ {"lowast", "8727"}, // asterisk operator, U+2217 ISOtech -->
+ {"radic", "8730"}, // square root = radical sign,U+221A ISOtech -->
+ {"prop", "8733"}, // proportional to, U+221D ISOtech -->
+ {"infin", "8734"}, // infinity, U+221E ISOtech -->
+ {"ang", "8736"}, // angle, U+2220 ISOamso -->
+ {"and", "8743"}, // logical and = wedge, U+2227 ISOtech -->
+ {"or", "8744"}, // logical or = vee, U+2228 ISOtech -->
+ {"cap", "8745"}, // intersection = cap, U+2229 ISOtech -->
+ {"cup", "8746"}, // union = cup, U+222A ISOtech -->
+ {"int", "8747"}, // integral, U+222B ISOtech -->
+ {"there4", "8756"}, // therefore, U+2234 ISOtech -->
+ {"sim", "8764"}, // tilde operator = varies with = similar to,U+223C ISOtech -->
+ // <!-- tilde operator is NOT the same character as the tilde, U+007E,although
+ // the same glyph might be used to represent both -->
+ {"cong", "8773"}, // approximately equal to, U+2245 ISOtech -->
+ {"asymp", "8776"}, // almost equal to = asymptotic to,U+2248 ISOamsr -->
+ {"ne", "8800"}, // not equal to, U+2260 ISOtech -->
+ {"equiv", "8801"}, // identical to, U+2261 ISOtech -->
+ {"le", "8804"}, // less-than or equal to, U+2264 ISOtech -->
+ {"ge", "8805"}, // greater-than or equal to,U+2265 ISOtech -->
+ {"sub", "8834"}, // subset of, U+2282 ISOtech -->
+ {"sup", "8835"}, // superset of, U+2283 ISOtech -->
+ // <!-- note that nsup, 'not a superset of, U+2283' is not covered by the
+ // Symbol font encoding and is not included. Should it be, for symmetry?
+ // It is in ISOamsn --> <!ENTITY nsub", "8836"},
+ // not a subset of, U+2284 ISOamsn -->
+ {"sube", "8838"}, // subset of or equal to, U+2286 ISOtech -->
+ {"supe", "8839"}, // superset of or equal to,U+2287 ISOtech -->
+ {"oplus", "8853"}, // circled plus = direct sum,U+2295 ISOamsb -->
+ {"otimes", "8855"}, // circled times = vector product,U+2297 ISOamsb -->
+ {"perp", "8869"}, // up tack = orthogonal to = perpendicular,U+22A5 ISOtech -->
+ {"sdot", "8901"}, // dot operator, U+22C5 ISOamsb -->
+ // <!-- dot operator is NOT the same character as U+00B7 middle dot -->
+ // <!-- Miscellaneous Technical -->
+ {"lceil", "8968"}, // left ceiling = apl upstile,U+2308 ISOamsc -->
+ {"rceil", "8969"}, // right ceiling, U+2309 ISOamsc -->
+ {"lfloor", "8970"}, // left floor = apl downstile,U+230A ISOamsc -->
+ {"rfloor", "8971"}, // right floor, U+230B ISOamsc -->
+ {"lang", "9001"}, // left-pointing angle bracket = bra,U+2329 ISOtech -->
+ // <!-- lang is NOT the same character as U+003C 'less than' or U+2039 'single left-pointing angle quotation
+ // mark' -->
+ {"rang", "9002"}, // right-pointing angle bracket = ket,U+232A ISOtech -->
+ // <!-- rang is NOT the same character as U+003E 'greater than' or U+203A
+ // 'single right-pointing angle quotation mark' -->
+ // <!-- Geometric Shapes -->
+ {"loz", "9674"}, // lozenge, U+25CA ISOpub -->
+ // <!-- Miscellaneous Symbols -->
+ {"spades", "9824"}, // black spade suit, U+2660 ISOpub -->
+ // <!-- black here seems to mean filled as opposed to hollow -->
+ {"clubs", "9827"}, // black club suit = shamrock,U+2663 ISOpub -->
+ {"hearts", "9829"}, // black heart suit = valentine,U+2665 ISOpub -->
+ {"diams", "9830"}, // black diamond suit, U+2666 ISOpub -->
+
+ // <!-- Latin Extended-A -->
+ {"OElig", "338"}, // -- latin capital ligature OE,U+0152 ISOlat2 -->
+ {"oelig", "339"}, // -- latin small ligature oe, U+0153 ISOlat2 -->
+ // <!-- ligature is a misnomer, this is a separate character in some languages -->
+ {"Scaron", "352"}, // -- latin capital letter S with caron,U+0160 ISOlat2 -->
+ {"scaron", "353"}, // -- latin small letter s with caron,U+0161 ISOlat2 -->
+ {"Yuml", "376"}, // -- latin capital letter Y with diaeresis,U+0178 ISOlat2 -->
+ // <!-- Spacing Modifier Letters -->
+ {"circ", "710"}, // -- modifier letter circumflex accent,U+02C6 ISOpub -->
+ {"tilde", "732"}, // small tilde, U+02DC ISOdia -->
+ // <!-- General Punctuation -->
+ {"ensp", "8194"}, // en space, U+2002 ISOpub -->
+ {"emsp", "8195"}, // em space, U+2003 ISOpub -->
+ {"thinsp", "8201"}, // thin space, U+2009 ISOpub -->
+ {"zwnj", "8204"}, // zero width non-joiner,U+200C NEW RFC 2070 -->
+ {"zwj", "8205"}, // zero width joiner, U+200D NEW RFC 2070 -->
+ {"lrm", "8206"}, // left-to-right mark, U+200E NEW RFC 2070 -->
+ {"rlm", "8207"}, // right-to-left mark, U+200F NEW RFC 2070 -->
+ {"ndash", "8211"}, // en dash, U+2013 ISOpub -->
+ {"mdash", "8212"}, // em dash, U+2014 ISOpub -->
+ {"lsquo", "8216"}, // left single quotation mark,U+2018 ISOnum -->
+ {"rsquo", "8217"}, // right single quotation mark,U+2019 ISOnum -->
+ {"sbquo", "8218"}, // single low-9 quotation mark, U+201A NEW -->
+ {"ldquo", "8220"}, // left double quotation mark,U+201C ISOnum -->
+ {"rdquo", "8221"}, // right double quotation mark,U+201D ISOnum -->
+ {"bdquo", "8222"}, // double low-9 quotation mark, U+201E NEW -->
+ {"dagger", "8224"}, // dagger, U+2020 ISOpub -->
+ {"Dagger", "8225"}, // double dagger, U+2021 ISOpub -->
+ {"permil", "8240"}, // per mille sign, U+2030 ISOtech -->
+ {"lsaquo", "8249"}, // single left-pointing angle quotation mark,U+2039 ISO proposed -->
+ // <!-- lsaquo is proposed but not yet ISO standardized -->
+ {"rsaquo", "8250"}, // single right-pointing angle quotation mark,U+203A ISO proposed -->
+ // <!-- rsaquo is proposed but not yet ISO standardized -->
+ {"euro", "8364"}, // -- euro sign, U+20AC NEW -->
+ };
+
+ /**
+ * <p>
+ * The set of entities supported by standard XML.
+ * </p>
+ */
+ public static final Entities XML;
+
+ /**
+ * <p>
+ * The set of entities supported by HTML 3.2.
+ * </p>
+ */
+ public static final Entities HTML32;
+
+ /**
+ * <p>
+ * The set of entities supported by HTML 4.0.
+ * </p>
+ */
+ public static final Entities HTML40;
+
+ static {
+ XML = new Entities();
+ XML.addEntities(BASIC_ARRAY);
+ XML.addEntities(APOS_ARRAY);
+ }
+
+ static {
+ HTML32 = new Entities();
+ HTML32.addEntities(BASIC_ARRAY);
+ HTML32.addEntities(ISO8859_1_ARRAY);
+ }
+
+ static {
+ HTML40 = new Entities();
+ fillWithHtml40Entities(HTML40);
+ }
+
+ /**
+ * <p>
+ * Fills the specified entities instance with HTML 40 entities.
+ * </p>
+ *
+ * @param entities
+ * the instance to be filled.
+ */
+ static void fillWithHtml40Entities(Entities entities) {
+ entities.addEntities(BASIC_ARRAY);
+ entities.addEntities(ISO8859_1_ARRAY);
+ entities.addEntities(HTML40_ARRAY);
+ }
+
+ static interface EntityMap {
+ /**
+ * <p>
+ * Add an entry to this entity map.
+ * </p>
+ *
+ * @param name
+ * the entity name
+ * @param value
+ * the entity value
+ */
+ void add(String name, int value);
+
+ /**
+ * <p>
+ * Returns the name of the entity identified by the specified value.
+ * </p>
+ *
+ * @param value
+ * the value to locate
+ * @return entity name associated with the specified value
+ */
+ String name(int value);
+
+ /**
+ * <p>
+ * Returns the value of the entity identified by the specified name.
+ * </p>
+ *
+ * @param name
+ * the name to locate
+ * @return entity value associated with the specified name
+ */
+ int value(String name);
+ }
+
+ static class PrimitiveEntityMap implements EntityMap {
+ private Map mapNameToValue = new HashMap();
+
+ private IntHashMap mapValueToName = new IntHashMap();
+
+ /**
+ * {@inheritDoc}
+ */
+ public void add(String name, int value) {
+ mapNameToValue.put(name, new Integer(value));
+ mapValueToName.put(value, name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String name(int value) {
+ return (String) mapValueToName.get(value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int value(String name) {
+ Object value = mapNameToValue.get(name);
+ if (value == null) {
+ return -1;
+ }
+ return ((Integer) value).intValue();
+ }
+ }
+
+ static abstract class MapIntMap implements Entities.EntityMap {
+ protected Map mapNameToValue;
+
+ protected Map mapValueToName;
+
+ /**
+ * {@inheritDoc}
+ */
+ public void add(String name, int value) {
+ mapNameToValue.put(name, new Integer(value));
+ mapValueToName.put(new Integer(value), name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String name(int value) {
+ return (String) mapValueToName.get(new Integer(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int value(String name) {
+ Object value = mapNameToValue.get(name);
+ if (value == null) {
+ return -1;
+ }
+ return ((Integer) value).intValue();
+ }
+ }
+
+ static class HashEntityMap extends MapIntMap {
+ /**
+ * Constructs a new instance of <code>HashEntityMap</code>.
+ */
+ public HashEntityMap() {
+ mapNameToValue = new HashMap();
+ mapValueToName = new HashMap();
+ }
+ }
+
+ static class TreeEntityMap extends MapIntMap {
+ /**
+ * Constructs a new instance of <code>TreeEntityMap</code>.
+ */
+ public TreeEntityMap() {
+ mapNameToValue = new TreeMap();
+ mapValueToName = new TreeMap();
+ }
+ }
+
+ static class LookupEntityMap extends PrimitiveEntityMap {
+ private String[] lookupTable;
+
+ private int LOOKUP_TABLE_SIZE = 256;
+
+ /**
+ * {@inheritDoc}
+ */
+ public String name(int value) {
+ if (value < LOOKUP_TABLE_SIZE) {
+ return lookupTable()[value];
+ }
+ return super.name(value);
+ }
+
+ /**
+ * <p>
+ * Returns the lookup table for this entity map. The lookup table is created if it has not been previously.
+ * </p>
+ *
+ * @return the lookup table
+ */
+ private String[] lookupTable() {
+ if (lookupTable == null) {
+ createLookupTable();
+ }
+ return lookupTable;
+ }
+
+ /**
+ * <p>
+ * Creates an entity lookup table of LOOKUP_TABLE_SIZE elements, initialized with entity names.
+ * </p>
+ */
+ private void createLookupTable() {
+ lookupTable = new String[LOOKUP_TABLE_SIZE];
+ for (int i = 0; i < LOOKUP_TABLE_SIZE; ++i) {
+ lookupTable[i] = super.name(i);
+ }
+ }
+ }
+
+ static class ArrayEntityMap implements EntityMap {
+ protected int growBy = 100;
+
+ protected int size = 0;
+
+ protected String[] names;
+
+ protected int[] values;
+
+ /**
+ * Constructs a new instance of <code>ArrayEntityMap</code>.
+ */
+ public ArrayEntityMap() {
+ names = new String[growBy];
+ values = new int[growBy];
+ }
+
+ /**
+ * Constructs a new instance of <code>ArrayEntityMap</code> specifying the size by which the array should
+ * grow.
+ *
+ * @param growBy
+ * array will be initialized to and will grow by this amount
+ */
+ public ArrayEntityMap(int growBy) {
+ this.growBy = growBy;
+ names = new String[growBy];
+ values = new int[growBy];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void add(String name, int value) {
+ ensureCapacity(size + 1);
+ names[size] = name;
+ values[size] = value;
+ size++;
+ }
+
+ /**
+ * Verifies the capacity of the entity array, adjusting the size if necessary.
+ *
+ * @param capacity
+ * size the array should be
+ */
+ protected void ensureCapacity(int capacity) {
+ if (capacity > names.length) {
+ int newSize = Math.max(capacity, size + growBy);
+ String[] newNames = new String[newSize];
+ System.arraycopy(names, 0, newNames, 0, size);
+ names = newNames;
+ int[] newValues = new int[newSize];
+ System.arraycopy(values, 0, newValues, 0, size);
+ values = newValues;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String name(int value) {
+ for (int i = 0; i < size; ++i) {
+ if (values[i] == value) {
+ return names[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int value(String name) {
+ for (int i = 0; i < size; ++i) {
+ if (names[i].equals(name)) {
+ return values[i];
+ }
+ }
+ return -1;
+ }
+ }
+
+ static class BinaryEntityMap extends ArrayEntityMap {
+
+ /**
+ * Constructs a new instance of <code>BinaryEntityMap</code>.
+ */
+ public BinaryEntityMap() {
+ super();
+ }
+
+ /**
+ * Constructs a new instance of <code>ArrayEntityMap</code> specifying the size by which the underlying array
+ * should grow.
+ *
+ * @param growBy
+ * array will be initialized to and will grow by this amount
+ */
+ public BinaryEntityMap(int growBy) {
+ super(growBy);
+ }
+
+ /**
+ * Performs a binary search of the entity array for the specified key. This method is based on code in
+ * {@link java.util.Arrays}.
+ *
+ * @param key
+ * the key to be found
+ * @return the index of the entity array matching the specified key
+ */
+ private int binarySearch(int key) {
+ int low = 0;
+ int high = size - 1;
+
+ while (low <= high) {
+ int mid = (low + high) >> 1;
+ int midVal = values[mid];
+
+ if (midVal < key) {
+ low = mid + 1;
+ } else if (midVal > key) {
+ high = mid - 1;
+ } else {
+ return mid; // key found
+ }
+ }
+ return -(low + 1); // key not found.
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void add(String name, int value) {
+ ensureCapacity(size + 1);
+ int insertAt = binarySearch(value);
+ if (insertAt > 0) {
+ return; // note: this means you can't insert the same value twice
+ }
+ insertAt = -(insertAt + 1); // binarySearch returns it negative and off-by-one
+ System.arraycopy(values, insertAt, values, insertAt + 1, size - insertAt);
+ values[insertAt] = value;
+ System.arraycopy(names, insertAt, names, insertAt + 1, size - insertAt);
+ names[insertAt] = name;
+ size++;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String name(int value) {
+ int index = binarySearch(value);
+ if (index < 0) {
+ return null;
+ }
+ return names[index];
+ }
+ }
+
+ // package scoped for testing
+ EntityMap map = new Entities.LookupEntityMap();
+
+ /**
+ * <p>
+ * Adds entities to this entity.
+ * </p>
+ *
+ * @param entityArray
+ * array of entities to be added
+ */
+ public void addEntities(String[][] entityArray) {
+ for (int i = 0; i < entityArray.length; ++i) {
+ addEntity(entityArray[i][0], Integer.parseInt(entityArray[i][1]));
+ }
+ }
+
+ /**
+ * <p>
+ * Add an entity to this entity.
+ * </p>
+ *
+ * @param name
+ * name of the entity
+ * @param value
+ * vale of the entity
+ */
+ public void addEntity(String name, int value) {
+ map.add(name, value);
+ }
+
+ /**
+ * <p>
+ * Returns the name of the entity identified by the specified value.
+ * </p>
+ *
+ * @param value
+ * the value to locate
+ * @return entity name associated with the specified value
+ */
+ public String entityName(int value) {
+ return map.name(value);
+ }
+
+ /**
+ * <p>
+ * Returns the value of the entity identified by the specified name.
+ * </p>
+ *
+ * @param name
+ * the name to locate
+ * @return entity value associated with the specified name
+ */
+ public int entityValue(String name) {
+ return map.value(name);
+ }
+
+ /**
+ * <p>
+ * Escapes the characters in a <code>String</code>.
+ * </p>
+ *
+ * <p>
+ * For example, if you have called addEntity(&quot;foo&quot;, 0xA1), escape(&quot;\u00A1&quot;) will return
+ * &quot;&amp;foo;&quot;
+ * </p>
+ *
+ * @param str
+ * The <code>String</code> to escape.
+ * @return A new escaped <code>String</code>.
+ */
+ public String escape(String str) {
+ StringWriter stringWriter = createStringWriter(str);
+ try {
+ this.escape(stringWriter, str);
+ } catch (IOException e) {
+ // This should never happen because ALL the StringWriter methods called by #escape(Writer, String) do not
+ // throw IOExceptions.
+ throw new RuntimeException(e);
+ }
+ return stringWriter.toString();
+ }
+
+ /**
+ * <p>
+ * Escapes the characters in the <code>String</code> passed and writes the result to the <code>Writer</code>
+ * passed.
+ * </p>
+ *
+ * @param writer
+ * The <code>Writer</code> to write the results of the escaping to. Assumed to be a non-null value.
+ * @param str
+ * The <code>String</code> to escape. Assumed to be a non-null value.
+ * @throws IOException
+ * when <code>Writer</code> passed throws the exception from calls to the {@link Writer#write(int)}
+ * methods.
+ *
+ * @see #escape(String)
+ * @see Writer
+ */
+ public void escape(Writer writer, String str) throws IOException {
+ int len = str.length();
+ for (int i = 0; i < len; i++) {
+ char c = str.charAt(i);
+ String entityName = this.entityName(c);
+ if (entityName == null) {
+ if (c > 0x7F) {
+ writer.write("&#");
+ writer.write(Integer.toString(c, 10));
+ writer.write(';');
+ } else {
+ writer.write(c);
+ }
+ } else {
+ writer.write('&');
+ writer.write(entityName);
+ writer.write(';');
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Unescapes the entities in a <code>String</code>.
+ * </p>
+ *
+ * <p>
+ * For example, if you have called addEntity(&quot;foo&quot;, 0xA1), unescape(&quot;&amp;foo;&quot;) will return
+ * &quot;\u00A1&quot;
+ * </p>
+ *
+ * @param str
+ * The <code>String</code> to escape.
+ * @return A new escaped <code>String</code>.
+ */
+ public String unescape(String str) {
+ int firstAmp = str.indexOf('&');
+ if (firstAmp < 0) {
+ return str;
+ } else {
+ StringWriter stringWriter = createStringWriter(str);
+ try {
+ this.doUnescape(stringWriter, str, firstAmp);
+ } catch (IOException e) {
+ // This should never happen because ALL the StringWriter methods called by #escape(Writer, String)
+ // do not throw IOExceptions.
+ throw new RuntimeException(e);
+ }
+ return stringWriter.toString();
+ }
+ }
+
+ /**
+ * Make the StringWriter 10% larger than the source String to avoid growing the writer
+ *
+ * @param str The source string
+ * @return A newly created StringWriter
+ */
+ private StringWriter createStringWriter(String str) {
+ return new StringWriter((int) (str.length() + (str.length() * 0.1)));
+ }
+
+ /**
+ * <p>
+ * Unescapes the escaped entities in the <code>String</code> passed and writes the result to the
+ * <code>Writer</code> passed.