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
@@ -16,6 +16,10 @@ module Spider; module Model; module Mappers
16
16
  true
17
17
  end
18
18
 
19
+ def pk
20
+ [Fixnum, {:autoincrement => true}]
21
+ end
22
+
19
23
  # Checks if the schema has some key to reach element.
20
24
  def have_references?(element) #:nodoc:
21
25
  element = @model.elements[element] unless element.is_a?(Element)
@@ -65,6 +69,11 @@ module Spider; module Model; module Mappers
65
69
  storage.execute(sql, *values)
66
70
  end
67
71
 
72
+ def truncate!
73
+ sql = storage.sql_truncate(schema.table)
74
+ storage.execute(sql)
75
+ end
76
+
68
77
  # def delete_all!
69
78
  # storage.execute("DELETE FROM #{schema.table}")
70
79
  # end
@@ -93,7 +102,6 @@ module Spider; module Model; module Mappers
93
102
  # next if (element.model? && (!(element_val = obj.get(element)) || !))
94
103
  next if (element.integrated?)
95
104
  element_val = nil if element.model? && element_val.is_a?(BaseModel) && !element_val.primary_keys_set?
96
-
97
105
  if (element.model?)
98
106
  element.model.primary_keys.each do |key|
99
107
  # FIXME! only works with one primary key
@@ -231,17 +239,18 @@ module Spider; module Model; module Mappers
231
239
  result.each do |row|
232
240
  set << map(nil, row, @model)
233
241
  end
242
+ set.modified = false
234
243
  return set
235
244
  end
236
245
 
237
246
  # Implements the Mapper#map method.
238
247
  # Converts a DB result row to an object.
239
- def map(request, result, obj)
240
- if (!request)
248
+ def map(request, result, obj_or_model)
249
+ if (!request || request == true)
241
250
  request = Request.new
242
251
  @model.elements_array.each{ |el| request.request(el.name) }
243
252
  end
244
- model = obj.is_a?(Class) ? obj : obj.model
253
+ model = obj_or_model.is_a?(Class) ? obj_or_model : obj_or_model.model
245
254
  data = {}
246
255
  request.keys.each do |element_name|
247
256
  element = @model.elements[element_name]
@@ -317,6 +326,10 @@ module Spider; module Model; module Mappers
317
326
  end
318
327
  end
319
328
  order, order_joins = prepare_order(query)
329
+ cnt = 0
330
+ order_joins.each do |oj|
331
+ oj[:as] ||= "ORD#{cnt+=1}" if joins.select{ |j| j[:to] == oj[:to] }.length > 0
332
+ end
320
333
  joins += order_joins if order_joins
321
334
  seen_fields = {}
322
335
  model_pks = []
@@ -792,6 +805,7 @@ module Spider; module Model; module Mappers
792
805
  # Returns a type accepted by the storage for type.
793
806
  def map_type(type)
794
807
  st = type
808
+ return Fixnum if st <= Spider::DataTypes::PK
795
809
  while (st && !storage.class.base_types.include?(st))
796
810
  st = Model.simplify_type(st)
797
811
  end
@@ -802,66 +816,26 @@ module Spider; module Model; module Mappers
802
816
  # Converts a value in one accepted by the storage.
803
817
  def map_value(type, value, mode=nil)
804
818
  return value if value.nil?
805
- if (type < Spider::DataType && value)
806
- value = type.from_value(value) unless value.is_a?(type)
807
- value = value.map(self.type)
808
- elsif type.class == Class && type.subclass_of?(Spider::Model::BaseModel)
809
- value = type.primary_keys.map{ |key| value.send(key.name) }
810
- else
811
- case type.name
812
- when 'Spider::DataTypes::Bool'
813
- value = value ? 1 : 0
814
- end
815
- end
816
- return value
817
- end
818
-
819
- # Prepares a value going to be bound to an insert or update statement
820
- def map_save_value(type, value, save_mode)
821
- value = map_value(type, value, :save)
822
- return @storage.value_for_save(Model.simplify_type(type), value, save_mode)
823
- end
824
-
825
- # Prepares a value for a condition.
826
- def map_condition_value(type, value)
827
- if value.is_a?(Range)
828
- return Range.new(map_condition_value(type, value.first), map_condition_value(type, value.last))
819
+
820
+ case type.name
821
+ when 'Spider::DataTypes::Bool'
822
+ value = value ? 1 : 0
823
+ else
824
+ value = super
829
825
  end
830
- return value if ( type.class == Class && type.subclass_of?(Spider::Model::BaseModel) )
831
- value = map_value(type, value, :condition)
832
- return @storage.value_for_condition(Model.simplify_type(type), value)
833
- end
834
-
835
- def storage_value_to_mapper(type, value)
836
- storage.value_to_mapper(type, value)
826
+
827
+ return value
837
828
  end
838
-
839
- # Converts a storage value back to the corresponding base type or DataType.
829
+
840
830
  def map_back_value(type, value)
841
- value = value[0] if value.class == Array
842
- value = storage_value_to_mapper(Model.simplify_type(type), value)
843
- if (type < Spider::DataType && type.maps_back_to)
844
- type = type.maps_back_to
845
- end
846
831
  case type.name
847
- when 'Fixnum'
848
- return value ? value.to_i : nil
849
- when 'Float'
850
- return value ? value.to_f : nil
851
832
  when 'Spider::DataTypes::Bool'
852
833
  return value if value.nil?
853
834
  return value == 1 ? true : false
854
835
  end
855
- return nil unless value
856
- case type.name
857
- when 'Date', 'DateTime'
858
- return type.parse(value) unless value.is_a?(Date)
859
- end
860
- if (type < Spider::DataType)
861
- value = type.from_value(value)
862
- end
863
- return value
864
- end
836
+ return super
837
+ end
838
+
865
839
 
866
840
  ##############################################################
867
841
  # Primary keys #
@@ -878,9 +852,10 @@ module Spider; module Model; module Mappers
878
852
  ##############################################################
879
853
 
880
854
  # UnitOfWork dependencies.
881
- def get_dependencies(obj, action)
855
+ def get_dependencies(task)
882
856
  deps = []
883
- task = MapperTask.new(obj, action)
857
+ obj = task.object
858
+ action = task.action
884
859
  deps = []
885
860
  case action
886
861
  when :keys
@@ -888,27 +863,50 @@ module Spider; module Model; module Mappers
888
863
  when :save
889
864
  @model.primary_keys.each do |key|
890
865
  if key.integrated? && !obj.element_has_value?(key)
891
- deps << [task, MapperTask.new(obj.get(key.integrated_from), :save)]
892
- end
893
- end
894
- elements = @model.elements.select{ |n, el| el.model? && obj.element_has_value?(el) && obj.element_modified?(el)}
895
- # n <-> n and n|1 <-> 1
896
- elements.select{ |n, el| !el.has_single_reverse? }.each do |name, element|
897
- set = obj.send(element.name)
898
- set = [set] unless set.is_a?(Enumerable)
899
- set.each do |set_obj|
900
- # set_obj.set(el.reverse, obj) if el.reverse
901
- deps << [task, MapperTask.new(set_obj, :keys)]
866
+ obj.get(key.integrated_from) # ensure super object is instantiated, so it gets processed later
902
867
  end
903
868
  end
904
- elements.select{ |n, el| el.has_single_reverse? }.each do |name, element|
905
- if (element.model? && element.type.mapper && element.type.mapper.class.write?)
906
- set = obj.send(element.name)
907
- set = [set] unless set.is_a?(Enumerable)
908
- set.each do |set_obj|
909
- # set_obj.set(el.reverse, obj) if el.reverse
910
- sub_task = MapperTask.new(set_obj, :save)
911
- deps << [sub_task, MapperTask.new(obj, :keys)]
869
+
870
+ elements = @model.elements.select{ |n, el| !el.integrated? && el.model? && obj.element_has_value?(el) && obj.element_modified?(el)}
871
+
872
+ elements.each do |name, element|
873
+ if have_references?(element)
874
+ el_obj = obj.send(element.name)
875
+ sub_task = MapperTask.new(el_obj, :keys)
876
+ deps << [task, sub_task]
877
+ else
878
+ if element.type.mapper && element.type.mapper.class.write?
879
+ el_val = obj.send(element.name)
880
+ if element.multiple?
881
+ set = el_val
882
+ if element.junction? && !element.attributes[:keep_junction]
883
+ set = obj.send("#{element.name}_junction")
884
+ end
885
+ delete_ass = nil
886
+ if set.modified # queryset modified
887
+ delete_ass = MapperTask.new(obj, :delete_associations, :element => element.name)
888
+ deps << [task, delete_ass]
889
+ end
890
+ prev_task = nil
891
+ set.each do |set_obj|
892
+ sub_task = MapperTask.new(set_obj, :save)
893
+ set_obj.set_modified(element.reverse) if element.reverse
894
+ if set_obj.class.attributes[:junction] && delete_ass
895
+ set_obj.class.primary_keys.each{ |pk| set_obj.set(pk, nil) }
896
+ end
897
+ if prev_task
898
+ deps << [sub_task, prev_task]
899
+ elsif delete_ass
900
+ deps << [sub_task, delete_ass]
901
+ else
902
+ deps << [sub_task, task]
903
+ end
904
+ prev_task = sub_task
905
+ end
906
+ else
907
+ el_val.set_modified(element.reverse)
908
+ deps << [task, MapperTask.new(el_val, :save)]
909
+ end
912
910
  end
913
911
  end
914
912
  end
@@ -916,6 +914,12 @@ module Spider; module Model; module Mappers
916
914
  return deps
917
915
  end
918
916
 
917
+ def execute_action(action, object, params={})
918
+ return super unless action == :delete_associations
919
+ el = object.class.elements[params[:element]]
920
+ delete_element_associations(object, el)
921
+ end
922
+
919
923
 
920
924
  ##############################################################
921
925
  # Schema management #
@@ -962,6 +966,14 @@ module Spider; module Model; module Mappers
962
966
  def storage_column_type(type, attributes)
963
967
  @storage.column_type(type, attributes)
964
968
  end
969
+
970
+ def base_type(type)
971
+ if type <= Spider::DataTypes::PK
972
+ Fixnum
973
+ else
974
+ super
975
+ end
976
+ end
965
977
 
966
978
  # Autogenerates schema. Returns a DbSchema.
967
979
  def generate_schema(schema=nil)
@@ -983,7 +995,7 @@ module Spider; module Model; module Mappers
983
995
  next if element.attributes[:added_reverse] && element.has_single_reverse?
984
996
  if (!element.model?)
985
997
  column = schema.columns[element.name]
986
- storage_type = Spider::Model.base_type(element.type)
998
+ storage_type = base_type(element.type)
987
999
  db_attributes = column.attributes if column
988
1000
  if (!db_attributes || db_attributes.empty?)
989
1001
  db_attributes = @storage.column_attributes(storage_type, element.attributes)
@@ -1005,6 +1017,7 @@ module Spider; module Model; module Mappers
1005
1017
  if (!element.multiple? && !element.attributes[:junction] && !element.attributes[:condition]) # 1/n <-> 1
1006
1018
  current_schema = schema.foreign_keys[element.name] || {}
1007
1019
  foreign_key_constraints = {}
1020
+ el_mapper = element.type.mapper
1008
1021
  element.type.primary_keys.each do |key|
1009
1022
  if key.model? # fixme: only works with single primary key model (after the first)
1010
1023
  curr_key = key
@@ -1023,7 +1036,8 @@ module Spider; module Model; module Mappers
1023
1036
  :precision => key_attributes[:precision]
1024
1037
  }
1025
1038
  column = current_schema[key.name]
1026
- column_type = element.attributes[:db_column_type] || @storage.column_type(key_type, key_attributes)
1039
+ key_storage_type = el_mapper.base_type(key_type)
1040
+ column_type = element.attributes[:db_column_type] || storage_column_type(key_storage_type, key_attributes)
1027
1041
  unless column
1028
1042
  column_name = element.attributes[:db_column_name] || @storage.column_name("#{element.name}_#{key.name}")
1029
1043
  column_attributes = @storage.column_attributes(key_type, key_attributes)
@@ -1181,11 +1195,12 @@ module Spider; module Model; module Mappers
1181
1195
  # Spider.logger.debug(fields[field])
1182
1196
  unless @storage.safe_schema_conversion?(current_fields[field], fields[field]) || force
1183
1197
  unsafe << field
1198
+ next
1184
1199
  end
1185
1200
  alter_fields << field_hash
1186
1201
  end
1187
1202
  end
1188
- raise SchemaSyncUnsafeConversion.new(unsafe) unless unsafe.empty?
1203
+
1189
1204
  end
1190
1205
  alter_attributes = {}
1191
1206
  if (current[:primary_keys] != attributes[:primary_keys])
@@ -1203,6 +1218,7 @@ module Spider; module Model; module Mappers
1203
1218
  :attributes => alter_attributes,
1204
1219
  :current => current
1205
1220
  })
1221
+ raise SchemaSyncUnsafeConversion.new(unsafe) unless unsafe.empty?
1206
1222
  end
1207
1223
 
1208
1224
  ##############################################################
@@ -0,0 +1,315 @@
1
+ require 'spiderfw/model/mappers/mapper'
2
+ require 'fileutils'
3
+
4
+
5
+ module Spider; module Model; module Mappers
6
+
7
+ class DocumentMapper < Spider::Model::Mapper
8
+ include Spider::Model::Storage::Document
9
+
10
+ def embedding(obj)
11
+ embedder_el = obj.embedder
12
+ return nil unless embedder_el
13
+ first_embedder = obj.get(embedder_el)
14
+ while first_embedder._subclass_object
15
+ first_embedder = first_embedder._subclass_object
16
+ end
17
+ reverse_el = embedder_el.type.elements[embedder_el.reverse]
18
+ path = "#{reverse_el.name}.#{obj.get(reverse_el.attributes[:embed_key])}"
19
+ parent_obj = obj.get(embedder_el)
20
+ # while parent_obj._subclass_object
21
+ # parent_obj = parent_obj._subclass_object
22
+ # end
23
+ parent_embedding = parent_obj.mapper.embedding(parent_obj)
24
+ if parent_embedding
25
+ first_embedder = parent_embedding[0]
26
+ path = "#{parent_embedding[0]}.#{path}"
27
+ end
28
+ [first_embedder, path]
29
+ end
30
+
31
+ def do_update(obj)
32
+ search_obj = obj
33
+ emb = embedding(obj)
34
+ path = nil
35
+ search_obj, path = emb if emb
36
+ condition = {}
37
+ # search_obj.class.primary_keys.each do |pk|
38
+ # name = pk.name == :id ? '_id' : pk.name
39
+ # condition[name] = map_condition_value(pk.type, search_obj.get(pk))
40
+ # end
41
+ condition["_id"] = obj.keys_string
42
+ set = {}
43
+ document_elements(obj).select{ |el| obj.element_modified?(el) }.each do |el|
44
+ name = el.name
45
+ name = "#{path}.#{name}" if path
46
+ if el.model?
47
+ if el.attributes[:embedded]
48
+ set[name] = obj_to_hash(obj.get(el), :embed_key => el.attributes[:embed_key])
49
+ else
50
+ set[name] = obj.get(el).keys_string
51
+ end
52
+ else
53
+ set[name] = map_save_value(el.type, obj.get(el), :update)
54
+ end
55
+ end
56
+ storage.update(search_obj.class.name, condition, set)
57
+ end
58
+
59
+ def do_insert(obj)
60
+ storage.insert(obj.class.name, obj_to_hash(obj))
61
+ end
62
+
63
+ def assign_pk(obj)
64
+ if obj.is_a?(QuerySet)
65
+ obj.each{ |o| assign_pk(o) }
66
+ return
67
+ end
68
+ obj.class.elements_array.select{ |el| el.type <= Spider::DataTypes::PK }.each do |el|
69
+ obj.set(el, storage.generate_pk) unless obj.element_has_value?(el)
70
+ end
71
+ end
72
+
73
+ def do_delete(condition, force)
74
+ query = Spider::Model::Query.new(condition)
75
+ objs = self.find(query)
76
+ return unless objs
77
+ objs.each do |obj|
78
+ storage.delete(obj.class.name, obj_to_hash(obj))
79
+ end
80
+ end
81
+
82
+ def before_save(obj, mode)
83
+ super
84
+ obj.class.elements_array.select{ |el|
85
+ el.attributes[:embedded] && !el.attributes[:extended_model] && obj.element_has_value?(el)
86
+ }.each do |el|
87
+ if el.multiple?
88
+ obj.get(el).each do |o|
89
+ o.mapper.before_save(o, mode)
90
+ end
91
+ else
92
+ o = obj.get(el)
93
+ next unless o
94
+ o.mapper.before_save(o, mode)
95
+ end
96
+ end
97
+ end
98
+
99
+ def document_elements(obj)
100
+ obj.class.elements_array.select{ |el| document_element?(el, obj.class) }
101
+ end
102
+
103
+ def document_element?(el, model=@model)
104
+ return true if el.attributes[:document_element]
105
+ return false if el.multiple? && !el.attributes[:embedded]
106
+ return false if el.attributes[:extended_model]
107
+ return false if el.attributes[:added_reverse]
108
+ return false if el.attributes[:computed_from]
109
+ return false if el.integrated? && !el.integrated_from.attributes[:extended_model]
110
+ return true
111
+
112
+ end
113
+
114
+ def embed?(element, val=nil)
115
+ return false unless element.attributes[:embedded] && element.model.embeddable?
116
+ return false if element.integrated?
117
+ model = nil
118
+ if val
119
+ model = val.is_a?(QuerySet) ? val.model : val.class
120
+ else
121
+ model = element.model
122
+ end
123
+ return false unless model.embeddable?
124
+
125
+ return true
126
+ end
127
+
128
+
129
+ def obj_to_hash(obj, options={})
130
+ h = {}
131
+ if obj.class == QuerySet
132
+ res = obj.map{ |obj| obj_to_hash(obj) }
133
+ if options[:embed_key]
134
+ h = {}
135
+ res.each do |val|
136
+ h[val[options[:embed_key].to_s]] = val
137
+ end
138
+ return h
139
+ end
140
+ return res
141
+ end
142
+
143
+ document_elements(obj).each do |el|
144
+ next if el.primary_key?
145
+ name = el.name
146
+ next if options[:skip] && options[:skip].include?(el.name)
147
+ val = obj.get(el)
148
+ sub_options = {}
149
+ hval = if el.model? && val
150
+ if embed?(el, val)
151
+ if el.multiple?
152
+ # if el.junction?
153
+ # sub_options[:skip] = [el.reverse]
154
+ # end
155
+ if el.attributes[:embed_key]
156
+ el_h = {}
157
+ val.each do |row|
158
+ el_h[row.get(el.attributes[:embed_key])] = row.mapper.obj_to_hash(row, sub_options)
159
+ end
160
+ el_h
161
+ else
162
+ h_mapper = val[0] && val[0].mapper.respond_to?(:obj_to_hash) ? val[0].mapper : self
163
+ val.map{ |row| h_mapper.obj_to_hash(row, sub_options) }
164
+ end
165
+ else
166
+ sub_mapper = val.mapper.respond_to?(:obj_to_hash) ? val.mapper : self
167
+ sub_mapper.obj_to_hash(val, sub_options)
168
+ end
169
+ else
170
+ val.keys_string
171
+ end
172
+ else
173
+ map_save_value(el.type, val)
174
+ end
175
+ h[name] = hval
176
+ end
177
+
178
+ assign_pk(obj)
179
+ h["_id"] = obj.keys_string
180
+
181
+ h
182
+ end
183
+
184
+ def have_references?(element)
185
+ element = @model.elements[element] unless element.is_a?(Element)
186
+ document_element?(element)
187
+ end
188
+
189
+ def someone_have_references?(element)
190
+ element = @model.elements[element] unless element.is_a?(Element)
191
+ if (element.integrated?)
192
+ return element.model.someone_have_references?(element.attributes[:integrated_from_element])
193
+ end
194
+ return have_references?(element)
195
+ end
196
+
197
+
198
+ def map(request, result, obj_or_model)
199
+ # FIXME: ignores request for now
200
+ model = obj_or_model.is_a?(Class) ? obj_or_model : obj_or_model.model
201
+ if (!request || request == true)
202
+ request = Request.new
203
+ model.elements_array.each{ |el| request.request(el.name) }
204
+ end
205
+ subclass_type_el = model.elements_array.select{ |cel| cel.attributes[:subclass_type] }.first
206
+ if subclass_type_el && subclass_type = result[subclass_type_el.name]
207
+ model = const_get_full(subclass_type)
208
+ end
209
+ embedded = {}
210
+ embedded_keys = model.elements_array.select{ |el| embed?(el) && !el.attributes[:extended_model] }.map{ |el| el.name }
211
+ # debugger
212
+ # embed?(:civilia_open_persona) if $DO_DEBUG
213
+ embedded_keys.each do |k|
214
+ embedded[k] = result.delete(k)
215
+ end
216
+ data = {}
217
+ request.keys.each do |element_name|
218
+ element = model.elements[element_name]
219
+ result_value = nil
220
+ next if !element || (element.integrated? && !element.integrated_from.embedded?) || !have_references?(element)
221
+ next if embedded[element_name]
222
+ if element.model?
223
+ pks = {}
224
+ keys_str = result[element_name]
225
+ next if keys_str.blank?
226
+ pks_array = element.model.split_keys_string(keys_str)
227
+ element.model.primary_keys.each_with_index do |key, i|
228
+ key_val = pks_array[i]
229
+ pks[key.name] = map_back_value(key.type, key_val)
230
+ end
231
+ # begin
232
+ data[element_name] = Spider::Model.get(element.model, pks, true)
233
+ # rescue IdentityMapperException
234
+ # null keys, nothing to set
235
+ # end
236
+ elsif !element.model?
237
+ data[element_name] = map_back_value(element.type, result[element_name])
238
+ end
239
+ end
240
+ obj = Spider::Model.get(model, data, true)
241
+ embedded.each do |k, v|
242
+ if !v
243
+ obj.set_loaded_value(k, nil) if request[k]
244
+ next
245
+ end
246
+ next if v.is_a?(Array) && v.empty?
247
+ el = obj.class.elements[k]
248
+ if el.multiple?
249
+ vals = []
250
+ if el.attributes[:embed_key]
251
+ vals = v.values
252
+ else
253
+ vals = v
254
+ end
255
+ qs = QuerySet.static(el.model)
256
+ el_model = el.model
257
+ el_mapper = el.model.mapper
258
+ if el.junction? && !el.attributes[:keep_junction]
259
+ el_model = el.type
260
+ el_mapper = el.model.mapper
261
+ end
262
+ vals.each do |val|
263
+ # FIXME: pass sub request
264
+ sub_obj = el_mapper.map(true, val, el_model)#Spider::Model.get(el_model, val, true)
265
+ qs << sub_obj
266
+ end
267
+ obj.set_loaded_value(k, qs)
268
+ else
269
+ # FIXME: pass sub request request[el.name]
270
+ sub_obj = el.model.mapper.map(true, v, el.model)
271
+ obj.set_loaded_value(k, sub_obj)
272
+ end
273
+
274
+ end
275
+ obj
276
+ end
277
+
278
+
279
+ def save_extended_models(obj, mode)
280
+ return
281
+ end
282
+
283
+ def children_for_unit_of_work(obj, action)
284
+ obj.class.elements_array.select{ |el|
285
+ el.model? && obj.element_has_value?(el) && !el.attributes[:embedded] && !el.attributes[:added_reverse]
286
+ }.map do |el|
287
+ obj.get(el)
288
+ end
289
+ end
290
+
291
+ def get_external_element(element, query, objects)
292
+ return objects if element.attributes[:embedded] || element.attributes[:extended_model]
293
+ super
294
+ end
295
+
296
+ def determine_save_mode(obj)
297
+ if @model.extended_models && !@model.extended_models.empty?
298
+ has_pks = true
299
+ @model.primary_keys.each do |pk|
300
+ if pk.integrated? && pk.integrated_from.attributes[:extended_model]
301
+ return super unless pk.integrated_from.attributes[:embedded]
302
+ unless obj.element_has_value?(pk)
303
+ has_pks = false
304
+ break
305
+ end
306
+ end
307
+ end
308
+ return has_pks ? :update : :insert
309
+ end
310
+ end
311
+
312
+
313
+ end
314
+
315
+ end; end; end