spiderfw 0.5.19 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. data/CHANGELOG +7 -0
  2. data/VERSION +1 -1
  3. data/apps/core/auth/lib/rbac.rb +7 -2
  4. data/apps/core/auth/models/mixins/rbac_provider.rb +66 -4
  5. data/apps/core/components/assets.rb +63 -33
  6. data/apps/core/components/public/js/jquery/{jquery-1.4.3.js → jquery-1.5.2.js} +2617 -1126
  7. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.apple.js +155 -0
  8. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.js +293 -0
  9. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/scrollable/scrollable.js +335 -0
  10. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.css +59 -0
  11. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.js +283 -0
  12. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/toolbox/toolbox.expose.js +224 -0
  13. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.dynamic.js +150 -0
  14. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.js +343 -0
  15. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.slide.js +78 -0
  16. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/button_bg.png +0 -0
  17. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/datepicker.gif +0 -0
  18. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/icon_sprite.png +0 -0
  19. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/progress_bar.gif +0 -0
  20. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_h_bg.gif +0 -0
  21. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_handles.png +0 -0
  22. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_v_bg.gif +0 -0
  23. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/tab_bg.gif +0 -0
  24. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/the_gradient.gif +0 -0
  25. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-anim_basic_16x16.gif +0 -0
  26. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  27. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  28. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_flat_10_000000_40x100.png +0 -0
  29. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  30. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  31. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  32. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  33. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  34. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  35. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_222222_256x240.png +0 -0
  36. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_228ef1_256x240.png +0 -0
  37. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ef8c08_256x240.png +0 -0
  38. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ffd27a_256x240.png +0 -0
  39. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ffffff_256x240.png +0 -0
  40. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/jquery-ui.custom.css +0 -0
  41. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-af.js +0 -0
  42. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ar-DZ.js +23 -0
  43. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ar.js +7 -8
  44. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-az.js +0 -0
  45. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-bg.js +0 -0
  46. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-bs.js +0 -0
  47. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ca.js +0 -0
  48. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-cs.js +0 -0
  49. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-da.js +0 -0
  50. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-de.js +0 -0
  51. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-el.js +0 -0
  52. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-AU.js +23 -0
  53. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-en-GB.js +0 -0
  54. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-NZ.js +23 -0
  55. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-eo.js +0 -0
  56. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-es.js +0 -0
  57. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-et.js +0 -0
  58. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-eu.js +0 -0
  59. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fa.js +0 -0
  60. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fi.js +0 -0
  61. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fo.js +0 -0
  62. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fr-CH.js +0 -0
  63. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fr.js +12 -10
  64. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-gl.js +23 -0
  65. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-he.js +0 -0
  66. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hr.js +0 -0
  67. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hu.js +1 -1
  68. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hy.js +0 -0
  69. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-id.js +0 -0
  70. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-is.js +0 -0
  71. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-it.js +0 -0
  72. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ja.js +0 -0
  73. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ko.js +0 -0
  74. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-kz.js +23 -0
  75. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-lt.js +0 -0
  76. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-lv.js +0 -0
  77. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ml.js +23 -0
  78. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ms.js +0 -0
  79. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-nl.js +0 -0
  80. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-no.js +23 -0
  81. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-pl.js +0 -0
  82. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-pt-BR.js +0 -0
  83. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-pt.js +22 -0
  84. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-rm.js +21 -0
  85. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ro.js +0 -0
  86. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ru.js +1 -1
  87. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sk.js +0 -0
  88. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sl.js +0 -0
  89. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sq.js +0 -0
  90. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sr-SR.js +0 -0
  91. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sr.js +0 -0
  92. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sv.js +0 -0
  93. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ta.js +0 -0
  94. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-th.js +1 -1
  95. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-tj.js +23 -0
  96. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-tr.js +0 -0
  97. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-uk.js +0 -0
  98. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-vi.js +0 -0
  99. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-CN.js +0 -0
  100. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-HK.js +0 -0
  101. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-TW.js +0 -0
  102. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.blind.js +3 -3
  103. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.bounce.js +3 -3
  104. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.clip.js +3 -3
  105. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.core.js +48 -15
  106. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.drop.js +3 -3
  107. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.explode.js +2 -2
  108. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/jquery.effects.fade.js +32 -0
  109. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.fold.js +3 -3
  110. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.highlight.js +2 -2
  111. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.pulsate.js +2 -2
  112. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.scale.js +4 -4
  113. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.shake.js +3 -3
  114. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.slide.js +4 -4
  115. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.transfer.js +2 -2
  116. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.accordion.js +33 -20
  117. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.autocomplete.js +104 -42
  118. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.button.js +35 -13
  119. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.core.js +111 -84
  120. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.datepicker.js +87 -46
  121. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.dialog.js +105 -75
  122. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.draggable.js +17 -15
  123. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.droppable.js +5 -5
  124. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.mouse.js +16 -11
  125. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.position.js +51 -32
  126. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.progressbar.js +24 -10
  127. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.resizable.js +7 -7
  128. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.selectable.js +3 -3
  129. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.slider.js +9 -7
  130. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.sortable.js +22 -20
  131. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.tabs.js +15 -14
  132. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.widget.js +50 -25
  133. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/GPL-LICENSE.txt +1 -1
  134. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/MIT-LICENSE.txt +3 -7
  135. data/apps/core/components/public/js/jquery/plugins/bsmselect/README.md +185 -0
  136. data/apps/core/components/public/js/jquery/plugins/bsmselect/css/jquery.bsmselect.css +64 -0
  137. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.compatibility.js +60 -0
  138. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.js +381 -0
  139. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.sortable.js +49 -0
  140. data/apps/core/components/public/js/plugins/sortable.js +16 -7
  141. data/apps/core/components/public/js/spider.js +60 -41
  142. data/apps/core/components/widgets/admin/admin.shtml +1 -1
  143. data/apps/core/components/widgets/list/list.shtml +2 -2
  144. data/apps/core/components/widgets/month_calendar/month_calendar.shtml +23 -20
  145. data/apps/core/components/widgets/switcher/switcher.rb +77 -21
  146. data/apps/core/components/widgets/switcher/templates/default.shtml +8 -0
  147. data/apps/core/components/widgets/switcher/templates/table.shtml +15 -0
  148. data/apps/core/components/widgets/table/table.rb +4 -1
  149. data/apps/core/components/widgets/table/table.shtml +10 -8
  150. data/apps/core/forms/public/css/form.css +9 -1
  151. data/apps/core/forms/public/date_time.js +14 -2
  152. data/apps/core/forms/public/input.js +1 -1
  153. data/apps/core/forms/public/select.js +4 -3
  154. data/apps/core/forms/tags/element_row.erb +11 -2
  155. data/apps/core/forms/widgets/inputs/date_time/date_time.rb +9 -0
  156. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +1 -1
  157. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  158. data/apps/core/forms/widgets/inputs/input/input.rb +0 -3
  159. data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
  160. data/apps/messenger/backends/email/sendmail.rb +20 -0
  161. data/apps/messenger/backends/email/smtp.rb +12 -14
  162. data/apps/messenger/backends/email/test.rb +20 -0
  163. data/apps/messenger/config/options.rb +9 -9
  164. data/apps/messenger/config/test.config.yml +2 -0
  165. data/apps/messenger/controllers/mixins/messenger_helper.rb +41 -15
  166. data/apps/messenger/lib/email_backend.rb +10 -0
  167. data/apps/messenger/messenger.rb +45 -26
  168. data/apps/messenger/test/features/attachments.feature +26 -0
  169. data/apps/messenger/test/features/messenger_helper.feature +31 -0
  170. data/apps/messenger/test/features/sending_email.feature +10 -0
  171. data/apps/messenger/test/features/step_definitions/common_steps.rb +11 -0
  172. data/apps/messenger/test/features/step_definitions/email_steps.rb +98 -0
  173. data/apps/messenger/test/features/support/env.rb +11 -0
  174. data/apps/messenger/test/files/test_file1.txt +1 -0
  175. data/apps/messenger/test/lib/controllers/mail_test_controller.rb +34 -0
  176. data/apps/messenger/test/templates/email/multipart.html.erb +1 -0
  177. data/apps/messenger/test/templates/email/multipart.txt.erb +1 -0
  178. data/apps/messenger/test/templates/email/simple.erb +1 -0
  179. data/apps/messenger/test/templates/email/vars.erb +1 -0
  180. data/lib/spiderfw/cmd/cmd.rb +4 -0
  181. data/lib/spiderfw/cmd/commands/webserver.rb +12 -59
  182. data/lib/spiderfw/config/configuration.rb +4 -0
  183. data/lib/spiderfw/config/options/spider.rb +25 -8
  184. data/lib/spiderfw/controller/controller.rb +10 -4
  185. data/lib/spiderfw/controller/first_responder.rb +6 -20
  186. data/lib/spiderfw/controller/http_controller.rb +2 -1
  187. data/lib/spiderfw/controller/mixins/http_mixin.rb +12 -1
  188. data/lib/spiderfw/controller/mixins/visual.rb +3 -16
  189. data/lib/spiderfw/env.rb +1 -1
  190. data/lib/spiderfw/http/server.rb +178 -2
  191. data/lib/spiderfw/model/base_model.rb +142 -111
  192. data/lib/spiderfw/model/data_type.rb +15 -0
  193. data/lib/spiderfw/model/datatypes/decimal.rb +8 -0
  194. data/lib/spiderfw/model/datatypes/pk.rb +29 -0
  195. data/lib/spiderfw/model/datatypes.rb +1 -0
  196. data/lib/spiderfw/model/element.rb +5 -1
  197. data/lib/spiderfw/model/extended_models/managed.rb +1 -1
  198. data/lib/spiderfw/model/junction.rb +23 -0
  199. data/lib/spiderfw/model/mappers/db_mapper.rb +96 -80
  200. data/lib/spiderfw/model/mappers/document_mapper.rb +315 -0
  201. data/lib/spiderfw/model/mappers/mapper.rb +164 -75
  202. data/lib/spiderfw/model/mixins/list.rb +1 -0
  203. data/lib/spiderfw/model/mixins/versioned.rb +63 -27
  204. data/lib/spiderfw/model/model.rb +36 -9
  205. data/lib/spiderfw/model/query_funcs.rb +3 -0
  206. data/lib/spiderfw/model/query_set.rb +21 -1
  207. data/lib/spiderfw/model/storage/base_storage.rb +259 -6
  208. data/lib/spiderfw/model/storage/{db/db_connection_pool.rb → connection_pool.rb} +25 -21
  209. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +25 -5
  210. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +1 -1
  211. data/lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb +2 -2
  212. data/lib/spiderfw/model/storage/db/connectors/oci8.rb +3 -4
  213. data/lib/spiderfw/model/storage/db/db_storage.rb +18 -219
  214. data/lib/spiderfw/model/storage/document/adapters/mongodb.rb +307 -0
  215. data/lib/spiderfw/model/storage/document/document.rb +7 -0
  216. data/lib/spiderfw/model/storage/document/document_storage.rb +34 -0
  217. data/lib/spiderfw/model/storage.rb +23 -11
  218. data/lib/spiderfw/model/unit_of_work.rb +45 -22
  219. data/lib/spiderfw/spider.rb +660 -0
  220. data/lib/spiderfw/templates/blocks/html.rb +4 -2
  221. data/lib/spiderfw/templates/blocks/run.rb +1 -1
  222. data/lib/spiderfw/templates/blocks/tag_if.rb +1 -1
  223. data/lib/spiderfw/templates/blocks/widget.rb +1 -1
  224. data/lib/spiderfw/templates/layout.rb +29 -5
  225. data/lib/spiderfw/templates/template.rb +72 -7
  226. data/lib/spiderfw/templates/template_blocks.rb +1 -1
  227. data/lib/spiderfw/test/capybara.rb +7 -0
  228. data/lib/spiderfw/test/cucumber.rb +12 -0
  229. data/lib/spiderfw/test/page_object.rb +29 -0
  230. data/lib/spiderfw/test/spec.rb +20 -0
  231. data/lib/spiderfw/test/stubs/mapper_stub.rb +18 -0
  232. data/lib/spiderfw/test/stubs/storage_stub.rb +23 -0
  233. data/lib/spiderfw/test/unit.rb +23 -0
  234. data/lib/spiderfw/test.rb +89 -0
  235. data/lib/spiderfw/utils/json.rb +6 -0
  236. data/lib/spiderfw/utils/logger.rb +17 -4
  237. data/lib/spiderfw/utils/loggers/apache_commons_logger.rb +61 -0
  238. data/lib/spiderfw/utils/monkey/date_time.rb +2 -2
  239. data/lib/spiderfw/utils/monkey/module.rb +3 -1
  240. data/lib/spiderfw/utils/profiling.rb +2 -2
  241. data/lib/spiderfw/widget/widget.rb +31 -13
  242. data/lib/spiderfw.rb +1 -597
  243. data/spider.gemspec +9 -10
  244. metadata +193 -132
  245. data/apps/admin/_init.rb +0 -9
  246. data/apps/admin/controllers/admin_controller.rb +0 -12
  247. data/apps/admin/widgets/dashboard_widget/dashboard_widget.rb +0 -8
  248. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/AUTHORS.txt +0 -30
  249. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery-ui-i18n.js +0 -1176
  250. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery.ui.datepicker-no.js +0 -23
  251. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/version.txt +0 -1
  252. data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.css +0 -64
  253. data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.js +0 -407
  254. data/apps/core/components/widgets/switcher/switcher.shtml +0 -17
  255. data/apps/master/po/master.pot +0 -400
@@ -1,6 +1,7 @@
1
1
  require 'spiderfw/model/mixins/state_machine'
2
2
  require 'spiderfw/model/element'
3
3
  require 'spiderfw/model/integrated_element'
4
+ require 'spiderfw/model/junction'
4
5
  require 'iconv'
5
6
 
6
7
  module Spider; module Model
@@ -73,6 +74,9 @@ module Spider; module Model
73
74
  attr_accessor :_subclass_object
74
75
  # This object won't be put into the identity mapper
75
76
  attr_accessor :_no_identity_mapper
77
+ # Elements that were modified since a load or a save (note: this only keeps track of changed references on the object;
78
+ # it doesn't consider if a associated object or QuerySet has changed. Use element_modified? to get that information)
79
+ attr_reader :_modified_elements
76
80
 
77
81
  class <<self
78
82
  # An Hash of model attributes. They can be used freely.
@@ -185,7 +189,7 @@ module Spider; module Model
185
189
  # the object.
186
190
  # :desc:: (true or Fixnum) Use this element for the to_s string. Multiple elements
187
191
  # with the :desc attribute will be joined by spaces; order may be specified if
188
- # a Fixnum is used for the parameter
192
+ # a Fixnum is used for the parameter
189
193
  #
190
194
  # Other attributes may be used by DataTypes (see #DataType::ClassMethods.take_attributes), and other code.
191
195
  # See also Element.
@@ -230,6 +234,7 @@ module Spider; module Model
230
234
  if attributes[:computed_from] && !attributes[:computed_from].is_a?(Enumerable)
231
235
  attributes[:computed_from] = [attributes[:computed_from]]
232
236
  end
237
+ attributes[:embedded] = true if attributes[:owned] && attributes[:embedded].nil?
233
238
  type.set_element_attributes(attributes) if type < Spider::DataType
234
239
 
235
240
 
@@ -274,11 +279,13 @@ module Spider; module Model
274
279
  assoc_type = first_model.const_set(assoc_type_name, Class.new(BaseModel))
275
280
  assoc_type.attributes[:sub_model] = self
276
281
  assoc_type.attributes[:sub_model_element] = name
277
- assoc_type.element(attributes[:junction_id], Fixnum, :primary_key => true, :autoincrement => true, :hidden => true) if attributes[:junction_id]
278
- assoc_type.element(self_name, self, :hidden => true, :reverse => name, :association => :choice, :junction_reference => true) # FIXME: must check if reverse exists?
282
+ embedder = attributes[:junction_embedded] == false ? false : true
283
+ assoc_type.element(attributes[:junction_id], Spider::DataTypes::PK, :primary_key => true, :autoincrement => true, :hidden => true) if attributes[:junction_id]
284
+ assoc_type.element(self_name, self, :hidden => true, :reverse => name, :association => :choice, :junction_reference => true, :embedder => embedder) # FIXME: must check if reverse exists?
279
285
  # FIXME! fix in case of clashes with existent elements
280
- assoc_type.element(other_name, orig_type, :association => :choice, :junction_reference => true)
286
+ assoc_type.element(other_name, orig_type, :association => :choice, :junction_reference => true, :embedded => attributes[:embedded])
281
287
  assoc_type.integrate(other_name, :hidden => true, :no_pks => true) # FIXME: in some cases we want the integrated elements
288
+ assoc_type.send(:include, Spider::Model::Junction)
282
289
  if (proc) # to be hidden, but the integrated el instead
283
290
  attributes[:extended] = true
284
291
  attributes[:keep_junction] = true
@@ -292,6 +299,7 @@ module Spider; module Model
292
299
  assoc_type.elements[attributes[:junction_their_element]].attributes[:polymorph] = attributes[:polymorph]
293
300
  attributes.delete(:polymorph)
294
301
  end
302
+ attributes[:embedded] = true unless attributes[:junction_embedded] == false
295
303
  end
296
304
 
297
305
 
@@ -318,6 +326,9 @@ module Spider; module Model
318
326
  rev[:junction_their_element] = self_name
319
327
  rev[:junction_our_element] = other_name
320
328
  end
329
+ if attributes[:embedded] && !attributes[:junction]
330
+ rev[:embedder] = true
331
+ end
321
332
  orig_type.element(rev_name, self, rev)
322
333
  end
323
334
  elsif (attributes[:add_multiple_reverse])
@@ -370,7 +381,8 @@ module Spider; module Model
370
381
  end
371
382
  if self.attributes[:integrated_from_elements]
372
383
  self.attributes[:integrated_from_elements].each do |imod, iel|
373
- imod.integrate_element(iel, self.elements[name]) unless imod.elements[name]
384
+ imod.integrate_element(iel, self.elements[name]) unless imod.elements[name] ||
385
+ (self.elements[name].reverse == iel && self.elements[name].type == imod)
374
386
  end
375
387
  end
376
388
  if (@subclasses)
@@ -399,7 +411,7 @@ module Spider; module Model
399
411
  element_methods = self.const_get(:ElementMethods)
400
412
 
401
413
  #instance variable getter
402
- element_methods.send(:define_method, name) do
414
+ element_methods.send(:define_method, name) do
403
415
  element = self.class.elements[name]
404
416
  raise "Internal error! Element method #{name} exists, but element not found" unless element
405
417
  return element.attributes[:fixed] if element.attributes[:fixed]
@@ -461,7 +473,7 @@ module Spider; module Model
461
473
  get(element.integrated_from).merge!(integrated_obj)
462
474
  end
463
475
  if !element.primary_key? && integrated_obj.element_modified?(name)
464
- @modified_elements[name] = true
476
+ @_modified_elements[name] = true
465
477
  end
466
478
  return res
467
479
  end
@@ -498,7 +510,7 @@ module Spider; module Model
498
510
  end
499
511
  end
500
512
  old_val = instance_variable_get(ivar)
501
- @modified_elements[name] = true if !element.primary_key? && (!was_loaded || val != old_val)
513
+ @_modified_elements[name] = true if !element.primary_key? && (!was_loaded || val != old_val)
502
514
  instance_variable_set(ivar, val)
503
515
  set_reverse(element, val) if element.model?
504
516
  if val && element.model? && !self.class.attributes[:no_type_check]
@@ -542,6 +554,7 @@ module Spider; module Model
542
554
  self.elements_array.select{ |e| e.integrated? && e.integrated_from.name == el}.each{ |e| remove_element(e) }
543
555
  self.const_get(:ElementMethods).send(:remove_method, :"#{el}") rescue NameError
544
556
  self.const_get(:ElementMethods).send(:remove_method, :"#{el}=") rescue NameError
557
+ @extended_models.delete(element.type) if element && @extended_models && @extended_models[element.type] == el
545
558
  @elements.delete(el)
546
559
  @elements_order.delete(el)
547
560
  @primary_keys.delete_if{ |pk| pk.name == el}
@@ -591,6 +604,7 @@ module Spider; module Model
591
604
  model.each_element do |el|
592
605
  next if params[:except].include?(el.name)
593
606
  next if elements[el.name] unless params[:overwrite] # don't overwrite existing elements
607
+ next if el.reverse == element_name && el.type == self
594
608
  integrate_element(element_name, el, params)
595
609
  end
596
610
  model.attributes[:integrated_from_elements] ||= []
@@ -599,6 +613,7 @@ module Spider; module Model
599
613
 
600
614
  def self.integrate_element(element_name, element_element, params={})
601
615
  el = element_element
616
+ el = self.elements[element_name].model.elements[el] if el.is_a?(Symbol)
602
617
  integrated_attributes = {}
603
618
  integrated_attributes[:primary_key] = false if params[:no_pks]
604
619
  integrated_attributes[:hidden] = params[:hidden] unless (params[:hidden].nil?)
@@ -739,9 +754,10 @@ module Spider; module Model
739
754
  @extended_models ||= {}
740
755
  @extended_models[model] = integrated_name
741
756
  attributes = {}
742
- attributes[:hidden] = true unless (params[:hide_integrated] == false)
757
+ attributes[:hidden] = true unless params[:hide_integrated] == false
743
758
  attributes[:delete_cascade] = params[:delete_cascade]
744
759
  attributes[:extended_model] = true
760
+ attributes[:embedded] = true unless params[:embedded] == false
745
761
  attributes[:add_reverse] = params[:reverse]
746
762
  integrated = element(integrated_name, model, attributes)
747
763
  integrate_options = {:keep_pks => true}.merge((params[:integrate_options] || {}))
@@ -762,7 +778,6 @@ module Spider; module Model
762
778
  # * :delete_cascade (bool) delete cascade the superclass instance. True by default.
763
779
  # * :no_local_pk (bool) do not define an id for this class
764
780
  def self.class_table_inheritance(params={})
765
-
766
781
  self.extend_model(superclass, params)
767
782
  end
768
783
 
@@ -897,6 +912,22 @@ module Spider; module Model
897
912
  !!self.attributes[:sub_model]
898
913
  end
899
914
 
915
+ def self.not_embeddable
916
+ @embeddable = false
917
+ end
918
+
919
+ def self.embeddable?
920
+ @embeddable.nil? ? true : @embeddable
921
+ end
922
+
923
+ def self.only_embedded
924
+ @only_embedded = true
925
+ end
926
+
927
+ def self.only_embedded?
928
+ @only_embedded
929
+ end
930
+
900
931
  ########################################################
901
932
  # Methods returning information about the elements #
902
933
  ########################################################
@@ -995,6 +1026,8 @@ module Spider; module Model
995
1026
  # Sets the url or the name of the storage to use
996
1027
  def self.use_storage(name=nil)
997
1028
  @use_storage = name if name
1029
+ @use_storage ||= self.attributes[:sub_model].use_storage if self.attributes[:sub_model]
1030
+ @use_storage ||= self.superclass.use_storage if self.superclass.respond_to?(:use_storage) && self.superclass.use_storage
998
1031
  @use_storage
999
1032
  end
1000
1033
 
@@ -1002,10 +1035,8 @@ module Spider; module Model
1002
1035
  # The storage to use can be set with #use_storage
1003
1036
  def self.storage
1004
1037
  return @storage if @storage
1005
- if (!@use_storage && self.attributes[:sub_model])
1006
- @use_storage = self.attributes[:sub_model].use_storage
1007
- end
1008
- return @use_storage ? get_storage(@use_storage) : get_storage
1038
+ st = self.use_storage
1039
+ return st ? get_storage(st) : get_storage
1009
1040
  end
1010
1041
 
1011
1042
  # Returns an instancethe storage corresponding to the storage_string if it is given,
@@ -1148,7 +1179,7 @@ module Spider; module Model
1148
1179
  @_autoload = true
1149
1180
  @_has_values = false
1150
1181
  @loaded_elements = {}
1151
- @modified_elements = {}
1182
+ @_modified_elements = {}
1152
1183
  @value_observers = nil
1153
1184
  @all_values_observers = nil
1154
1185
  @_extra = {}
@@ -1183,6 +1214,10 @@ module Spider; module Model
1183
1214
  return obj
1184
1215
  end
1185
1216
 
1217
+ def self.load_or_create(values)
1218
+ self.load(values) || self.create(values)
1219
+ end
1220
+
1186
1221
  def self.get(values)
1187
1222
  return self.new(values) unless Spider::Model.identity_mapper
1188
1223
  values = [values] unless values.is_a?(Hash) || values.is_a?(Array)
@@ -1339,6 +1374,11 @@ module Spider; module Model
1339
1374
  end
1340
1375
  end
1341
1376
 
1377
+ # Returns the object's embedder element, if any
1378
+ def embedder
1379
+ self.class.elements_array.select{ |el| el.attributes[:embedder] && self.element_has_value?(el) }[0]
1380
+ end
1381
+
1342
1382
 
1343
1383
  #################################################
1344
1384
  # Get and set #
@@ -1427,7 +1467,7 @@ module Spider; module Model
1427
1467
  # appropriate type.
1428
1468
  def self.prepare_value(element, value)
1429
1469
  element = self.class.elements[element] unless element.is_a?(Element)
1430
- if (element.type < Spider::DataType)
1470
+ if element.type < Spider::DataType && element.type.force_wrap?
1431
1471
  value = element.type.from_value(value) unless value.is_a?(element.type)
1432
1472
  if value
1433
1473
  element.type.take_attributes.each do |a|
@@ -1442,7 +1482,9 @@ module Spider; module Model
1442
1482
  elsif element.model?
1443
1483
  value.autoload(autoload?, true) if value && value.respond_to?(:autolad)
1444
1484
  else
1445
- case element.type.name
1485
+ type = element.type
1486
+ type = mapper.base_type(type) if type < Spider::DataType && type.mapper_dependant?
1487
+ case type.name
1446
1488
  when 'Date', 'DateTime'
1447
1489
  return nil if value.is_a?(String) && value.empty?
1448
1490
  parsed = nil
@@ -1474,8 +1516,9 @@ module Spider; module Model
1474
1516
  def set_loaded_value(element, value, mark_loaded=true)
1475
1517
  element_name = element.is_a?(Element) ? element.name : element
1476
1518
  element = self.class.elements[element_name]
1477
- if (element.integrated?)
1478
- get(element.integrated_from).set_loaded_value(element.integrated_from_element, value)
1519
+ if element.integrated?
1520
+ integrated = get(element.integrated_from)
1521
+ integrated.set_loaded_value(element.integrated_from_element, value) if integrated
1479
1522
  else
1480
1523
  value = prepare_child(element.name, value)
1481
1524
  current = instance_variable_get("@#{element_name}")
@@ -1485,8 +1528,8 @@ module Spider; module Model
1485
1528
  end
1486
1529
  value.loaded = true if (value.is_a?(QuerySet))
1487
1530
  element_loaded(element_name) if mark_loaded
1488
- set_reverse(element, value) if element.model?
1489
- @modified_elements[element_name] = false
1531
+ set_reverse(element, value) if element.model? && value
1532
+ @_modified_elements[element_name] = false
1490
1533
  end
1491
1534
 
1492
1535
  # Records that the element has been loaded.
@@ -1608,7 +1651,7 @@ module Spider; module Model
1608
1651
  # If a block is given, the current autoload setting will be restored after yielding.
1609
1652
  def save_mode
1610
1653
  prev_autoload = autoload?
1611
- self.autoload = :save_mode
1654
+ self.autoload = :save_mode unless prev_autoload == false
1612
1655
  if (block_given?)
1613
1656
  yield
1614
1657
  self.autoload = prev_autoload
@@ -1631,6 +1674,13 @@ module Spider; module Model
1631
1674
  return true
1632
1675
  end
1633
1676
 
1677
+ # Like ==, but other must be of the same class (no subclasses)
1678
+ def eql?(other)
1679
+ return false unless other.class == self.class
1680
+ return self == other
1681
+ end
1682
+
1683
+
1634
1684
  ##############################################################
1635
1685
  # Iterators #
1636
1686
  ##############################################################
@@ -1666,7 +1716,16 @@ module Spider; module Model
1666
1716
 
1667
1717
  # Returns a string with the primary keys joined by ','
1668
1718
  def keys_string
1669
- self.class.primary_keys.map{ |pk| self.get(pk) }.join(',')
1719
+ self.class.keys_string(self.primary_keys)
1720
+ end
1721
+
1722
+
1723
+ def self.keys_string(keys)
1724
+ keys.join(',')
1725
+ end
1726
+
1727
+ def self.split_keys_string(string)
1728
+ string.split(',')
1670
1729
  end
1671
1730
 
1672
1731
 
@@ -1698,9 +1757,9 @@ module Spider; module Model
1698
1757
  # Returns true if the element value has been modified since instantiating or loading
1699
1758
  def element_modified?(element)
1700
1759
  element = self.class.get_element(element)
1701
- set_mod = @modified_elements[element.name]
1760
+ set_mod = @_modified_elements[element.name]
1702
1761
  return set_mod if set_mod
1703
- if (element.integrated?)
1762
+ if element.integrated?
1704
1763
  return false unless integrated = get_no_load(element.integrated_from)
1705
1764
  return integrated.element_modified?(element.integrated_from_element)
1706
1765
  end
@@ -1719,9 +1778,9 @@ module Spider; module Model
1719
1778
 
1720
1779
  # Returns true if any element, or any child object, has been modified
1721
1780
  def modified?
1722
- return true unless @modified_elements.reject{ |key, val| !val }.empty?
1781
+ return true unless @_modified_elements.reject{ |key, val| !val }.empty?
1723
1782
  self.class.elements_array.select{ |el|
1724
- !el.model? && element_has_value?(el) && el.type.is_a?(Spider::DataType)
1783
+ element_has_value?(el) && (el.type.is_a?(Spider::DataType) || el.multiple?)
1725
1784
  }.each do |el|
1726
1785
  return true if get(el).modified?
1727
1786
  end
@@ -1735,18 +1794,30 @@ module Spider; module Model
1735
1794
 
1736
1795
  # Given elements are set as modified
1737
1796
  def set_modified(request) #:nodoc:
1797
+ request = {request => true} unless request.is_a?(Hash)
1738
1798
  request.each do |key, val| # FIXME: go deep
1739
- @modified_elements[key] = true
1799
+ key = key.name if key.is_a?(Element)
1800
+ @_modified_elements[key] = true
1740
1801
  end
1741
1802
  end
1742
1803
 
1743
1804
  # Resets modified elements
1744
1805
  def reset_modified_elements(*elements) #:nodoc:
1745
1806
  if (elements.length > 0)
1746
- elements.each{ |el_name| @modified_elements.delete(el_name) }
1807
+ elements.each{ |el_name| @_modified_elements.delete(el_name) }
1747
1808
  else
1748
- @modified_elements = {}
1809
+ @_modified_elements = {}
1810
+ end
1811
+ elements = self.class.elements_array.map{ |el| el.name } if elements.empty?
1812
+ elements.each do |el_name|
1813
+ val = instance_variable_get("@#{el_name}")
1814
+ val.modified = false if val.is_a?(QuerySet)
1749
1815
  end
1816
+ self.class.elements_array.select{ |el| el.attributes[:integrated_model] && self.element_has_value?(el) }.each do |el|
1817
+ self.get(el).reset_modified_elements(elements)
1818
+ end
1819
+
1820
+ nil
1750
1821
  end
1751
1822
 
1752
1823
  # Returns true if all primary keys have a value; false if some primary key
@@ -1787,7 +1858,7 @@ module Spider; module Model
1787
1858
  else
1788
1859
  Spider.logger.warn("Element #{el.name} overwritten in #{obj.inspect}") if our_val && our_val != val
1789
1860
  end
1790
- set_loaded_value(el, val, false) unless val.nil? && element.multiple?
1861
+ set_loaded_value(el, val, false) # unless val.nil? && element.multiple?
1791
1862
  end
1792
1863
  self
1793
1864
  end
@@ -1945,33 +2016,16 @@ module Spider; module Model
1945
2016
  # Saves the object to the storage
1946
2017
  # (see Mapper#save)
1947
2018
  def save
1948
- if @unit_of_work
1949
- @unit_of_work.add(self)
1950
- return
1951
- end
1952
- save_mode do
1953
- before_save unless unit_of_work_available?
1954
- if unit_of_work_available?
1955
- Spider.current[:unit_of_work].add(self)
1956
- if @unit_of_work
1957
- @unit_of_work.commit
1958
- Spider::Model.stop_unit_of_work
1959
- if @uow_identity_mapper
1960
- Spider.current[:identity_mapper] = nil
1961
- @uow_identity_mapper = nil
1962
- end
1963
- @unit_of_work = nil
1964
- end
1965
- return
1966
- else
1967
- save!
1968
- end
2019
+ saving(:save) do
2020
+ before_save
2021
+ save!
1969
2022
  end
1970
2023
  self
1971
2024
  end
1972
2025
 
1973
2026
  def save!
1974
2027
  mapper.save(self)
2028
+ after_save
1975
2029
  self
1976
2030
  end
1977
2031
 
@@ -1983,79 +2037,54 @@ module Spider; module Model
1983
2037
  end
1984
2038
 
1985
2039
  def insert
1986
- if @unit_of_work
1987
- @unit_of_work.add(self)
1988
- return
1989
- end
1990
- save_mode do
1991
- before_save unless unit_of_work_available?
1992
- if unit_of_work_available?
1993
- Spider.current[:unit_of_work].add(self, :save, :force => :insert)
1994
- if @unit_of_work
1995
- @unit_of_work.commit
1996
- Spider::Model.stop_unit_of_work
1997
- if @uow_identity_mapper
1998
- Spider.current[:identity_mapper] = nil
1999
- @uow_identity_mapper = nil
2000
- end
2001
- @unit_of_work = nil
2002
- end
2003
- return
2004
- else
2005
- insert!
2006
- end
2040
+ saving(:insert) do
2041
+ before_save
2042
+ insert!
2007
2043
  end
2008
2044
  self
2009
2045
  end
2010
2046
 
2011
- def unit_of_work_available?
2012
- Spider.current[:unit_of_work] && !Spider.current[:unit_of_work].running?
2013
- end
2014
-
2015
2047
  # Inserts the object in the storage
2016
2048
  # Note: if the object is already present in the storage and unique indexes are enforced,
2017
2049
  # this will raise an error.
2018
2050
  # (See Mapper#insert).
2019
2051
  def insert!
2020
2052
  mapper.insert(self)
2021
- reset_modified_elements
2053
+ after_save
2022
2054
  end
2023
2055
 
2024
2056
  # Updates the object in the storage
2025
2057
  # Note: the update will silently fail if the object is not present in the storage
2026
2058
  # (see Mapper#update).
2027
2059
  def update
2060
+ saving(:update) do
2061
+ before_save
2062
+ update!
2063
+ end
2064
+ end
2065
+
2066
+ def update!
2028
2067
  mapper.update(self)
2029
- reset_modified_elements
2068
+ after_save
2030
2069
  end
2031
2070
 
2071
+ def unit_of_work_available?
2072
+ Spider.current[:unit_of_work] && !Spider.current[:unit_of_work].running?
2073
+ end
2074
+
2075
+
2032
2076
  # Deletes the object from the storage
2033
2077
  # (see Mapper#delete).
2034
2078
  def delete
2035
- if @unit_of_work
2036
- @unit_of_work.add(self, :delete)
2037
- return
2038
- end
2039
- before_delete unless Spider.current[:unit_of_work]
2040
- if Spider.current[:unit_of_work]
2041
- Spider.current[:unit_of_work].add(self, :delete)
2042
- if @unit_of_work
2043
- @unit_of_work.commit
2044
- @unit_of_work.stop
2045
- if @uow_identity_mapper
2046
- Spider.current[:identity_mapper] = nil
2047
- @uow_identity_mapper = nil
2048
- end
2049
- @unit_of_work = nil
2050
- end
2051
- return
2052
- else
2079
+ saving(:delete) do
2080
+ before_delete
2053
2081
  delete!
2054
2082
  end
2055
2083
  end
2056
2084
 
2057
2085
  def delete!
2058
2086
  mapper.delete(self)
2087
+ after_delete
2059
2088
  end
2060
2089
 
2061
2090
  def before_delete
@@ -2064,22 +2093,24 @@ module Spider; module Model
2064
2093
  def before_save
2065
2094
  end
2066
2095
 
2067
- def use_unit_of_work
2068
- had_uow = true
2069
- unless Spider.current[:unit_of_work]
2070
- had_wow = false
2071
- @unit_of_work = Spider::Model.start_unit_of_work
2072
- end
2073
- unless Spider::Model.identity_mapper
2074
- @uow_identity_mapper = Spider::Model::IdentityMapper.new
2075
- Spider.current[:identity_mapper] = @uow_identity_mapper
2076
- @uow_identity_mapper.put(self) if self.primary_keys_set?
2077
- end
2078
- # Spider.current[:unit_of_work].add(self)
2079
- Spider.current[:unit_of_work]
2080
- return had_uow
2096
+ def after_save
2097
+ reset_modified_elements
2098
+ autoload(@_saving[:prev_autoload]) if @_saving
2099
+ @_saving = nil
2081
2100
  end
2082
2101
 
2102
+ def after_delete
2103
+ end
2104
+
2105
+ def saving(mode, &proc)
2106
+ @_saving ||= { :prev_autoload => save_mode }
2107
+ if unit_of_work_available?
2108
+ Spider.current[:unit_of_work].add(self, mode)
2109
+ else
2110
+ yield
2111
+ end
2112
+ end
2113
+
2083
2114
  # Loads the object from the storage
2084
2115
  # Acceptable arguments are:
2085
2116
  # * a Query object, or
@@ -60,6 +60,21 @@ module Spider
60
60
  attributes[:auto] = true if @autogenerated && attributes[:auto] != false
61
61
  end
62
62
 
63
+ # Returns whether values need to be wrapped in this DataType when they are set on models instances.
64
+ def force_wrap?
65
+ true
66
+ end
67
+
68
+ # Indicates that the actual type of this DataType depends on the mapper (e.g. PK)
69
+ def mapper_dependant
70
+ @mapper_dependant = true
71
+ end
72
+
73
+ # Returns whether this DataTypes is mapper dependant
74
+ def mapper_dependant?
75
+ @mapper_dependant
76
+ end
77
+
63
78
  end
64
79
 
65
80
  # Returns the DataType attributes, as set in the Model Element.
@@ -30,6 +30,14 @@ module Spider; module DataTypes
30
30
  to_f
31
31
  end
32
32
 
33
+ def to_json(options=nil)
34
+ to_f.to_json
35
+ end
36
+
37
+ def attributes
38
+ {:scale => 2}.merge(super)
39
+ end
40
+
33
41
 
34
42
 
35
43
  end
@@ -0,0 +1,29 @@
1
+ require 'delegate'
2
+
3
+ module Spider; module DataTypes
4
+
5
+ class PK < Delegator
6
+ include DataType
7
+ mapper_dependant
8
+
9
+ def initialize(obj)
10
+ @delegate_sd_obj = obj
11
+ end
12
+
13
+ def __getobj__
14
+ @delegate_sd_obj
15
+ end
16
+ alias :obj :__getobj__
17
+
18
+ def __setobj__(obj)
19
+ @delegate_sd_obj = obj
20
+ end
21
+
22
+ def self.force_wrap?
23
+ false
24
+ end
25
+
26
+
27
+ end
28
+
29
+ end; end
@@ -1,4 +1,5 @@
1
1
  require 'spiderfw/model/data_type'
2
+ require 'spiderfw/model/datatypes/pk'
2
3
  require 'spiderfw/model/datatypes/bool'
3
4
  require 'spiderfw/model/datatypes/text'
4
5
  require 'spiderfw/model/datatypes/decimal'
@@ -104,7 +104,7 @@ module Spider; module Model
104
104
  self.attributes[:reverse]
105
105
  end
106
106
 
107
- # True if the element has a reverse, and it is not multiple (i.e., the relationship is 1 <-> 1|n)
107
+ # True if the element has a reverse, and that reverse is not multiple
108
108
  def has_single_reverse?
109
109
  return true if self.attributes[:reverse] && !model.elements[self.attributes[:reverse]].multiple?
110
110
  end
@@ -129,6 +129,10 @@ module Spider; module Model
129
129
  self.attributes[:owned]
130
130
  end
131
131
 
132
+ def embedded?
133
+ self.attributes[:embedded]
134
+ end
135
+
132
136
  # True if the element is generated on save by the model or the mapper.
133
137
  def autogenerated?
134
138
  return (self.attributes[:auto] || self.attributes[:autoincrement])
@@ -12,7 +12,7 @@ module Spider; module Model
12
12
  # Other modules may be mixed-in to add default functionality to managed models.
13
13
 
14
14
  class Managed < BaseModel
15
- element :id, Fixnum, {
15
+ element :id, PK, {
16
16
  :primary_key => true,
17
17
  :autoincrement => true,
18
18
  :read_only => true,
@@ -0,0 +1,23 @@
1
+ module Spider; module Model
2
+
3
+ module Junction
4
+
5
+ def self.included(klass)
6
+ klass.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def has_added_elements?
12
+ junction_added_elements.length > 0
13
+ end
14
+
15
+ def junction_added_elements
16
+ self.elements_array.select{ |el| !el.integrated? && !el.attributes[:junction_id] && !el.attributes[:junction_reference] }
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end; end