wontomedia 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. data/COPYING +661 -0
  2. data/COPYING.DOCUMENTATION +450 -0
  3. data/LICENSE +661 -0
  4. data/README.markdown +56 -0
  5. data/Rakefile +185 -0
  6. data/VERSION.yml +4 -0
  7. data/app/controllers/admin_controller.rb +144 -0
  8. data/app/controllers/application_controller.rb +29 -0
  9. data/app/controllers/connections_controller.rb +150 -0
  10. data/app/controllers/items_controller.rb +365 -0
  11. data/app/helpers/connections_helper.rb +67 -0
  12. data/app/helpers/format_helper.rb +154 -0
  13. data/app/helpers/items_helper.rb +105 -0
  14. data/app/models/category_item.rb +23 -0
  15. data/app/models/connection.rb +210 -0
  16. data/app/models/individual_item.rb +23 -0
  17. data/app/models/item.rb +86 -0
  18. data/app/models/property_item.rb +23 -0
  19. data/app/models/qualified_item.rb +23 -0
  20. data/app/views/admin/index.html.erb +74 -0
  21. data/app/views/connections/_index_outbound_links.html.erb +48 -0
  22. data/app/views/connections/_spo_select_controls.html.erb +151 -0
  23. data/app/views/connections/edit.html.erb +70 -0
  24. data/app/views/connections/index.html.erb +84 -0
  25. data/app/views/connections/new.html.erb +61 -0
  26. data/app/views/connections/show.html.erb +110 -0
  27. data/app/views/items/_active_content.html.erb +26 -0
  28. data/app/views/items/_content_examples.html.erb +55 -0
  29. data/app/views/items/_core_tasks.html.erb +23 -0
  30. data/app/views/items/_form_fields.html.erb +69 -0
  31. data/app/views/items/_list_outbound_links.html.erb +58 -0
  32. data/app/views/items/_screen_select.html.erb +24 -0
  33. data/app/views/items/_show_outbound_links.html.erb +70 -0
  34. data/app/views/items/_topic_list.html.erb +26 -0
  35. data/app/views/items/_type_select.html.erb +47 -0
  36. data/app/views/items/edit.html.erb +63 -0
  37. data/app/views/items/index.html.erb +74 -0
  38. data/app/views/items/new.html.erb +124 -0
  39. data/app/views/items/newpop.html.erb +58 -0
  40. data/app/views/items/show.html.erb +209 -0
  41. data/app/views/layouts/_amazon_ads.html.erb +55 -0
  42. data/app/views/layouts/_glossary_help_box.html.erb +43 -0
  43. data/app/views/layouts/_google_ads.html.erb +40 -0
  44. data/app/views/layouts/_language_select.html.erb +24 -0
  45. data/app/views/layouts/_login_controls.html.erb +24 -0
  46. data/app/views/layouts/_master_help.html.erb +24 -0
  47. data/app/views/layouts/_navigation_menu.html.erb +39 -0
  48. data/app/views/layouts/_search_box.html.erb +27 -0
  49. data/app/views/layouts/_status_msgs.html.erb +25 -0
  50. data/app/views/layouts/application.html.erb +67 -0
  51. data/app/views/layouts/base.html.erb +93 -0
  52. data/app/views/layouts/home.html.erb +67 -0
  53. data/app/views/layouts/popup.html.erb +23 -0
  54. data/assets/wontomedia-sample.rb +47 -0
  55. data/config/asset_packages.yml +44 -0
  56. data/config/boot.rb +110 -0
  57. data/config/cucumber.yml +65 -0
  58. data/config/database-mysql-development.yml +47 -0
  59. data/config/database-mysql.yml +26 -0
  60. data/config/environment.rb +94 -0
  61. data/config/environments/cucumber.rb +29 -0
  62. data/config/environments/development.rb +26 -0
  63. data/config/environments/production.rb +33 -0
  64. data/config/environments/test.rb +31 -0
  65. data/config/initializers/inflections.rb +19 -0
  66. data/config/initializers/mime_types.rb +14 -0
  67. data/config/initializers/new_rails_defaults.rb +26 -0
  68. data/config/locales/en.yml +14 -0
  69. data/config/routes.rb +37 -0
  70. data/db/fixtures/connections.yml +96 -0
  71. data/db/fixtures/items.yml +277 -0
  72. data/db/migrate/20090312212805_create_items.rb +31 -0
  73. data/db/migrate/20090406221320_create_connections.rb +32 -0
  74. data/db/migrate/20090411014503_add_type_for_item_subclasses.rb +29 -0
  75. data/db/migrate/20090415142152_rename_item_type.rb +31 -0
  76. data/db/migrate/20090518022918_rename_object_and_self.rb +33 -0
  77. data/db/migrate/20090529171442_add_flags_to_items.rb +27 -0
  78. data/db/migrate/20090529171508_add_flags_to_connections.rb +27 -0
  79. data/db/migrate/20090605213800_flags_columns_not_null.rb +29 -0
  80. data/db/migrate/20090605215028_flags_columns_default_zero.rb +29 -0
  81. data/db/schema.rb +30 -0
  82. data/default-custom/app/views/items/_home_extern_list.html.erb +32 -0
  83. data/default-custom/app/views/items/_home_introductory_text.html.erb +70 -0
  84. data/default-custom/app/views/items/home.html.erb +77 -0
  85. data/default-custom/public/images/logo.png +0 -0
  86. data/default-custom/public/images/logo.svg +74 -0
  87. data/default-custom/public/stylesheets/wm.css +301 -0
  88. data/doc/README.markdown +44 -0
  89. data/doc/README_FOR_APP +82 -0
  90. data/doc/customization.markdown +93 -0
  91. data/doc/scripts/rake-customize.markdown +83 -0
  92. data/lib/helpers/connection_helper.rb +41 -0
  93. data/lib/helpers/item_helper.rb +141 -0
  94. data/lib/helpers/tripple_navigation.rb +158 -0
  95. data/lib/tasks/cucumber.rake +83 -0
  96. data/lib/tasks/customize.rake +70 -0
  97. data/lib/tasks/db.rake +65 -0
  98. data/lib/tasks/javascript_testing_tasks.rake +176 -0
  99. data/public/404.html +50 -0
  100. data/public/422.html +50 -0
  101. data/public/500.html +53 -0
  102. data/public/dispatch.cgi +20 -0
  103. data/public/dispatch.fcgi +34 -0
  104. data/public/dispatch.rb +20 -0
  105. data/public/favicon.ico +0 -0
  106. data/public/images/blank_error_icon.png +0 -0
  107. data/public/images/blank_status_icon.png +0 -0
  108. data/public/images/error_error_icon.png +0 -0
  109. data/public/images/error_status_icon.png +0 -0
  110. data/public/images/good_status_icon.png +0 -0
  111. data/public/images/help_icon.png +0 -0
  112. data/public/images/twitter_icon.png +0 -0
  113. data/public/images/warn_error_icon.png +0 -0
  114. data/public/images/working_status_icon.gif +0 -0
  115. data/public/javascripts/application.js +56 -0
  116. data/public/javascripts/controls.js +963 -0
  117. data/public/javascripts/dragdrop.js +973 -0
  118. data/public/javascripts/effects.js +1128 -0
  119. data/public/javascripts/event.simulate.js +64 -0
  120. data/public/javascripts/fancybox.js +43 -0
  121. data/public/javascripts/forConnectionsForms.js +218 -0
  122. data/public/javascripts/forItemsForms.js +511 -0
  123. data/public/javascripts/itemCreatePopup.js +115 -0
  124. data/public/javascripts/itemTitleToName.js +119 -0
  125. data/public/javascripts/jquery.js +4376 -0
  126. data/public/javascripts/modalbox.js +502 -0
  127. data/public/javascripts/prototype.js +4320 -0
  128. data/public/javascripts/reconcileJQueryAndPrototype.js +19 -0
  129. data/public/robots.txt +7 -0
  130. data/public/stylesheets/blank.gif +0 -0
  131. data/public/stylesheets/fancy_close.png +0 -0
  132. data/public/stylesheets/fancy_loading.png +0 -0
  133. data/public/stylesheets/fancy_nav_left.png +0 -0
  134. data/public/stylesheets/fancy_nav_right.png +0 -0
  135. data/public/stylesheets/fancy_shadow_e.png +0 -0
  136. data/public/stylesheets/fancy_shadow_n.png +0 -0
  137. data/public/stylesheets/fancy_shadow_ne.png +0 -0
  138. data/public/stylesheets/fancy_shadow_nw.png +0 -0
  139. data/public/stylesheets/fancy_shadow_s.png +0 -0
  140. data/public/stylesheets/fancy_shadow_se.png +0 -0
  141. data/public/stylesheets/fancy_shadow_sw.png +0 -0
  142. data/public/stylesheets/fancy_shadow_w.png +0 -0
  143. data/public/stylesheets/fancy_title_left.png +0 -0
  144. data/public/stylesheets/fancy_title_main.png +0 -0
  145. data/public/stylesheets/fancy_title_over.png +0 -0
  146. data/public/stylesheets/fancy_title_right.png +0 -0
  147. data/public/stylesheets/fancybox.css +333 -0
  148. data/public/stylesheets/modalbox.css +110 -0
  149. data/public/stylesheets/scaffold.css +36 -0
  150. data/public/stylesheets/spinner.gif +0 -0
  151. data/script/about +4 -0
  152. data/script/console +3 -0
  153. data/script/cucumber +10 -0
  154. data/script/dbconsole +3 -0
  155. data/script/destroy +3 -0
  156. data/script/generate +3 -0
  157. data/script/performance/benchmarker +3 -0
  158. data/script/performance/profiler +3 -0
  159. data/script/performance/request +3 -0
  160. data/script/plugin +3 -0
  161. data/script/process/inspector +3 -0
  162. data/script/process/reaper +3 -0
  163. data/script/process/spawner +3 -0
  164. data/script/runner +3 -0
  165. data/script/server +3 -0
  166. data/vendor/plugins/asset_packager/CHANGELOG +122 -0
  167. data/vendor/plugins/asset_packager/README +178 -0
  168. data/vendor/plugins/asset_packager/Rakefile +22 -0
  169. data/vendor/plugins/asset_packager/about.yml +8 -0
  170. data/vendor/plugins/asset_packager/init.rb +2 -0
  171. data/vendor/plugins/asset_packager/install.rb +1 -0
  172. data/vendor/plugins/asset_packager/lib/jsmin.rb +205 -0
  173. data/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb +212 -0
  174. data/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb +39 -0
  175. data/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake +23 -0
  176. data/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb +100 -0
  177. data/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb +140 -0
  178. data/vendor/plugins/asset_packager/test/asset_packager_test.rb +92 -0
  179. data/vendor/plugins/asset_packager/test/asset_packages.yml +20 -0
  180. data/vendor/plugins/asset_packager/test/assets/javascripts/application.js +2 -0
  181. data/vendor/plugins/asset_packager/test/assets/javascripts/bar.js +4 -0
  182. data/vendor/plugins/asset_packager/test/assets/javascripts/controls.js +815 -0
  183. data/vendor/plugins/asset_packager/test/assets/javascripts/dragdrop.js +913 -0
  184. data/vendor/plugins/asset_packager/test/assets/javascripts/effects.js +958 -0
  185. data/vendor/plugins/asset_packager/test/assets/javascripts/foo.js +4 -0
  186. data/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js +2006 -0
  187. data/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css +16 -0
  188. data/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css +16 -0
  189. data/vendor/plugins/asset_packager/test/assets/stylesheets/header.css +16 -0
  190. data/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css +16 -0
  191. data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css +16 -0
  192. data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css +16 -0
  193. metadata +265 -0
@@ -0,0 +1,93 @@
1
+ Copyright (C) 2010 - Glen E. Ivey
2
+ (see the end of this file for copyright/licensing information)
3
+
4
+ Mechanism for Per-Instalation WontoMedia Customization
5
+ ======================================================
6
+
7
+ WontoMedia is a web application intended to be installed in a large
8
+ number and in a wide variety of systems. For many of these systems,
9
+ some of the included text or functionality may not be appropriate. We
10
+ have tried to separate portions of WontoMedia that may need to be
11
+ customized (replaced) for different installations into separate files
12
+ from the core application.
13
+
14
+ To make things easier for those WontoMedia users who are also
15
+ developers, we have segregated the instances of those files particular
16
+ to a given WontoMedia installation from the core application files.
17
+ Unfortunately, the conventions used by Ruby-on-Rails make things
18
+ significantly easier if all files are located together based on
19
+ function. If we included customization files in the standard Rails
20
+ directory hierarchy, then changes to them might inadvertently be
21
+ included in commit's to the Git repositories for WontoMedia, or other
22
+ people's changes to the sample version of the customization files
23
+ might accidentally be applied to the custom versions for a particular
24
+ installation.
25
+
26
+ We have reconciled these conflicting needs as follows:
27
+
28
+ * customization files are kept in one or more "customization
29
+ directories" separate from any of the standard Rails directories
30
+
31
+ * within a customization directory is a sub-directory hierarchy
32
+ that mirrors the standard Rails directory structure
33
+
34
+ * a set of customization files, that can be viewed as examples and be
35
+ used as-is to get a new WontoMedia installation going, is located
36
+ in:
37
+
38
+ wontomedia/default-custom
39
+
40
+ * a rake task is provided that will create symbolic links to all
41
+ files found under all customization directories from the matching
42
+ point in the WontoMedia root directory hierarchy. This allows
43
+ files "outside" of the normal directory structure (for version
44
+ control purposes) to appear "inside" where Rails expects them
45
+ during execution.
46
+
47
+ * a script is executed by rake (first step in "rake test:policies")
48
+ that finds all symbolic links in the project directory, and
49
+ replaces the file $GIT_DIR/info/exclude with a list of them. In a
50
+ different type of project, where keeping symbolic links under
51
+ version control was important, this would be a problem. However,
52
+ we have chosen the convention that symbolic links will be used in
53
+ the WontoMedia directory structure only for installation
54
+ customization. This step prevents any symbolic links from being
55
+ committed to Git, and therefore any individual installations
56
+ configuration of cusomization files from being incorporated into
57
+ any updates to WontoMedia.
58
+
59
+ The "exclude" file is used, rather than .gitignore, so that an
60
+ individual site's extensions can include files above and beyond the
61
+ minimal set of entry points that the WontoMedia core expects. If
62
+ .gitignore were used, then people would still have to manually
63
+ prevent customization files they added to their system from being
64
+ listed in Git commits they share with others.
65
+
66
+ * a script is executed by rake (run as part of "rake test:policies")
67
+ that recurses through the "default-custom" directory and fails that
68
+ a symbolic link exists in the application directory hierarchy for
69
+ each file under default-custom. In this way, the content of
70
+ default-custom not only provides a sample of customization files,
71
+ but serves as the definition for all of the files referenced from
72
+ portions of the core application.
73
+
74
+ The "customize" rake task is documented in
75
+
76
+ wontomedia/doc/script/rake-customize.markdown
77
+
78
+ and its use in creating a new, *uncustomized* WontoMedia installation
79
+ is mentioned in the WontoMedia wiki at:
80
+
81
+ http://wiki.wontology.org/InstallFromScratch
82
+ http://wiki.wontology.org/SettingUpYourDevelopmentEnvironment
83
+
84
+ ----------------------------------------------------------------
85
+
86
+ Permission is granted to copy, distribute and/or modify this
87
+ document under the terms of the GNU Free Documentation License,
88
+ Version 1.3, published by the Free Software Foundation; with no
89
+ Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
90
+
91
+ You should have received a copy of the GNU Free Documentation
92
+ License along with document in the file COPYING.DOCUMENTATION. If
93
+ not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,83 @@
1
+ Copyright (C) 2010 - Glen E. Ivey
2
+ (see the end of this file for copyright/licensing information)
3
+
4
+ # rake customize[directory-path:directory-path]
5
+
6
+ This rake task operates recursively through each directory provided,
7
+ and creates symbolic links to the files in that directory from
8
+ matching, same-named points in the main wontomedia installation
9
+ directory. It is intended to merge installation-specific
10
+ customization files maintained in separate directories (and version
11
+ control repositories) from the core of the WontoMedia web application.
12
+
13
+ As many directories as desired can be specified on the command line
14
+ (one minimum). The directory name list must be enclosed in square
15
+ brackets, and placed immediately after the task name "customize" (no
16
+ space). Each directory is separated from the next by a colon (like a
17
+ UNIX PATH). Recall that rake always operates relative to the top
18
+ directory of your project, regardless of your working directory when
19
+ you execute the rake command. Therefore, any relative paths you
20
+ include are evaluated relative to the root of the wontomedia
21
+ installation directory.
22
+
23
+ Depending on your shell and the content of your directory names, you
24
+ may need to include quotation marks or escape characters in the
25
+ command line you type in order for rake to receive a command line
26
+ formatted as shown. In particular, the entire parameterized task,
27
+ from the task name ("customize") through the closing square-bracket
28
+ must be parsed by the shell and passed to rake as a single
29
+ command-line argument.
30
+
31
+ As an example of the "customize" task's operation, the command
32
+
33
+ rake customize[~/myWontology]
34
+
35
+ will recursively find all files and directories under your
36
+ "myWontology" directory, and make it appear as though they've been
37
+ copied into your WontoMedia directory (in which the rake command was
38
+ executed). Assuming the following directory structure/content:
39
+
40
+ ~/myWontology/app/views/items/_home_introductory_text.html.erb
41
+
42
+ this rake task will do the equivalent of:
43
+
44
+ ln -s ~/myWontology/app/views/items/_home_introductory_text.html.erb [wontomedia-root]/app/views/items
45
+
46
+ However, the rake task uses absolute paths, so it will have to be
47
+ re-executed if you later move either the WontoMedia directory or one
48
+ of the customization directories in your file system.
49
+
50
+ In this example, there was only one argument directory and only one
51
+ file, so only one link was created. This task will also create any
52
+ directories needed to hold the created links, although this was not
53
+ needed for the example above because a standard Ruby-on-Rails
54
+ directory was used.
55
+
56
+ When more than one directory is specified on the command line, this
57
+ task processes them in the order provided. If multiple directory
58
+ arguments are provided, and two or more of them contain a file with
59
+ the same relative path and name, only the link from the last
60
+ (right-most) directory will remain when the task is complete. This
61
+ allows installation customizations to be derived from each other. For
62
+ example, running the following command from the root of your
63
+ WontoMedia directory:
64
+
65
+ rake customize[default-custom:~/myWontology]
66
+
67
+ will first create links to the minimum set of required customization
68
+ files under the "default-custom" directory, and then create links to
69
+ the files in your "myWontology" directory. Your myWontology could
70
+ then contain as little as a single file (with the correct,
71
+ Rails-matching relative path) that replaced only a single link
72
+ pointing into the default-custom directory.
73
+
74
+ ----------------------------------------------------------------
75
+
76
+ Permission is granted to copy, distribute and/or modify this
77
+ document under the terms of the GNU Free Documentation License,
78
+ Version 1.3, published by the Free Software Foundation; with no
79
+ Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
80
+
81
+ You should have received a copy of the GNU Free Documentation
82
+ License along with document in the file COPYING.DOCUMENTATION. If
83
+ not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,41 @@
1
+ #--
2
+ # WontoMedia - a wontology web application
3
+ # Copyright (C) 2010 - Glen E. Ivey
4
+ # www.wontology.com
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License version
8
+ # 3 as published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program in the file COPYING and/or LICENSE. If not,
17
+ # see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+
21
+ # This module provides a container for methods that manipulate or
22
+ # transform Connection objects.
23
+ module ConnectionHelper
24
+
25
+ # This method renders a multi-line string in the 'n3' format (aka
26
+ # 'Notation3' standardized by the W3C, see
27
+ # http://en.wikipedia.org/wiki/Notation3 for an introduction) from
28
+ # an array of Connection models.
29
+ #
30
+ # This is currently a trivial but correct implementation. It supports
31
+ # our current data model, but will need a significant upgrade when
32
+ # WontoMedia begins to support reiffied edges (blank nodes), etc.
33
+ def self.connection_array_to_n3(connections)
34
+ result = ""
35
+ connections.each do |connection|
36
+ result << "<##{connection.subject.name}> <##{connection.predicate.name}> "
37
+ result << "<##{connection.obj.name}> .\n"
38
+ end
39
+ result
40
+ end
41
+ end
@@ -0,0 +1,141 @@
1
+ #--
2
+ # WontoMedia - a wontology web application
3
+ # Copyright (C) 2010 - Glen E. Ivey
4
+ # www.wontology.com
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License version
8
+ # 3 as published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program in the file COPYING and/or LICENSE. If not,
17
+ # see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+
21
+ # This module provides a container for methods that manipulate or
22
+ # transform Item objects, and constants related to Item objects. The
23
+ # constants are related to the single-table-inheritance structure
24
+ # between Item and its specialized child classes, and don't fit into
25
+ # any of the individual model classes themselves.
26
+ module ItemHelper
27
+
28
+ ITEM_CLASS_NAME = "Item"
29
+ ITEM_CATEGORY_CLASS_NAME = "CategoryItem"
30
+ ITEM_INDIVIDUAL_CLASS_NAME = "IndividualItem"
31
+ ITEM_PROPERTY_CLASS_NAME = "PropertyItem"
32
+ ITEM_QUALIFIED_CLASS_NAME = "QualifiedItem"
33
+
34
+ ITEM_SUBTYPES_FROM_TEXT = {
35
+ "item" => Item, "Item" => Item,
36
+ "category" => CategoryItem, "CategoryItem" => CategoryItem,
37
+ "individual" => IndividualItem,
38
+ "IndividualItem" => IndividualItem,
39
+ "property" => PropertyItem, "PropertyItem" => PropertyItem,
40
+ "qualified-connection" => QualifiedItem, "QualifiedItem" => QualifiedItem
41
+ }
42
+ ITEM_CLASSNAME_TO_SUBTYPE_SHORT = {
43
+ "CategoryItem" => 'category', "IndividualItem" => 'individual',
44
+ "PropertyItem" => 'property', "QualifiedItem" => 'qualified'
45
+ }
46
+ ITEM_SUBTYPES_TO_HUMAN = {
47
+ 'CategoryItem' => 'Category',
48
+ 'IndividualItem' => 'Individual',
49
+ 'PropertyItem' => 'Property Type',
50
+ 'QualifiedItem' => 'Qualified Connection'
51
+ }
52
+
53
+
54
+ # This method is a wrapper for Rails' Item.find(), except that it
55
+ # checks the sti_type of the item found, then creates and returns an
56
+ # instance of the correct Item child class.
57
+ def self.find_typed_item(*args)
58
+ n = Item.find(*args)
59
+ if n.nil? ||
60
+ n.sti_type.nil? ||
61
+ ITEM_SUBTYPES_FROM_TEXT[n.sti_type].nil?
62
+ return nil
63
+ end
64
+
65
+ # I think that this statement:
66
+ # ITEM_SUBTYPES_FROM_TEXT[n.sti_type].find(*args)
67
+ # ought to work. But it doesn't. So instead, we do the following:
68
+ class_of_item_to_find = case n.sti_type
69
+ when "Item" then Item
70
+ when "item" then Item
71
+ when "CategoryItem" then CategoryItem
72
+ when "category" then CategoryItem
73
+ when "IndividualItem" then IndividualItem
74
+ when "individual" then IndividualItem
75
+ when "PropertyItem" then PropertyItem
76
+ when "property" then PropertyItem
77
+ when "QualifiedItem" then QualifiedItem
78
+ when "qualified-connection" then QualifiedItem
79
+ end
80
+ class_of_item_to_find.find(*args)
81
+ end
82
+
83
+ # Use this method in place of <tt>new Item</tt> in order to create
84
+ # an Item child class (STI) instance matching a type string you have
85
+ # available. (Note: if you know when writing a piece of code what
86
+ # item subtype you're trying to create, simply create that directly
87
+ # rather than using this method. _E.g._, <tt>new
88
+ # PropertyItem</tt>.)
89
+ def self.new_typed_item(type_string, *args)
90
+ if type_string.nil?
91
+ return nil
92
+ end
93
+ if ITEM_SUBTYPES_FROM_TEXT[type_string].nil?
94
+ type_string = type_string.singularize
95
+ if ITEM_SUBTYPES_FROM_TEXT[type_string].nil?
96
+ return nil
97
+ end
98
+ end
99
+
100
+ # absolutely no idea why this ugly thing works, but simply hash lookup
101
+ # below causes failure deep in Rails' guts during new()
102
+ class_of_item_to_create = case type_string
103
+ when "Item" then Item
104
+ when "item" then Item
105
+ when "CategoryItem" then CategoryItem
106
+ when "category" then CategoryItem
107
+ when "IndividualItem" then IndividualItem
108
+ when "individual" then IndividualItem
109
+ when "PropertyItem" then PropertyItem
110
+ when "property" then PropertyItem
111
+ when "QualifiedItem" then QualifiedItem
112
+ when "qualified-connection" then QualifiedItem
113
+ end
114
+ # class_of_item_to_create = ITEM_SUBTYPES_FROM_TEXT[type_string]
115
+ new_item = class_of_item_to_create.new(*args)
116
+ new_item.flags = 0
117
+ new_item
118
+ end
119
+
120
+ # Takes an Item object, +n+, and returns a symbol-indexed hash
121
+ # containing each of the Item's data fields.
122
+ def self.item_to_hash(n)
123
+ # Really ought to be doing this programatically from the schema....
124
+ { :id => n.id, :name => n.name, :title => n.title, :flags => n.flags,
125
+ :description => n.description, :sti_type => n.sti_type }
126
+ end
127
+
128
+
129
+ # This method is equivalent to Rails' Item.all(), except that it
130
+ # only finds/returns "noun"-type items (Category and Individual
131
+ # items, but not Property or Qualified items).
132
+ def self.nouns
133
+ CategoryItem.all + IndividualItem.all
134
+ end
135
+
136
+ # This method is equivalent to Rails' Item.all(), except that it
137
+ # only finds/returns Items with an sti_type other than Qualified.
138
+ def self.not_qualified
139
+ CategoryItem.all + IndividualItem.all + PropertyItem.all
140
+ end
141
+ end
@@ -0,0 +1,158 @@
1
+ #--
2
+ # WontoMedia - a wontology web application
3
+ # Copyright (C) 2010 - Glen E. Ivey
4
+ # www.wontology.com
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License version
8
+ # 3 as published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program in the file COPYING and/or LICENSE. If not,
17
+ # see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+
21
+ # This module contains methods for navigating through (walking) the
22
+ # inheritence hierarchy between the properties of connections. They
23
+ # allow callers to make queries about a property, and receive answers
24
+ # that take into account the 'sub_property_of' relationships between
25
+ # the immediately queried property and the property inheritance tree.
26
+ module TrippleNavigation
27
+
28
+ # This method finds all existing PropertyItem's that are super
29
+ # properties of the PropertyItem identified by +predicate_id+. The
30
+ # immediate super properties of an item are the objects of any
31
+ # connection of the form "item sub_property_of object". The set of
32
+ # super properties found by this method includes immediate super
33
+ # properties and all of _their_ super properties. This method
34
+ # accepts a block, and iteratively yields _its original argument_
35
+ # and the _IDs_ of the argument property's super properties to that
36
+ # block.
37
+ def self.relation_and_all_superproperties(predicate_id, &block)
38
+ yield predicate_id
39
+
40
+ spo_id = Item.find_by_name("sub_property_of").id
41
+ connections = Connection.all( :conditions => [
42
+ "subject_id = ? AND predicate_id = ?", predicate_id, spo_id ])
43
+ connections.each do |e|
44
+ relation_and_all_superproperties(e.obj_id, &block)
45
+ end
46
+ end
47
+
48
+ # This method finds all existing PropertyItem's that are sub
49
+ # properties of the PropertyItem identified by +predicate_id+. The
50
+ # immediate sub properties of an item are the subjects of any
51
+ # connection of the form "subject sub_property_of item". The set of
52
+ # sub properties found by this method includes immediate sub
53
+ # properties and all of _their_ sub properties. This method accepts
54
+ # a block, and iteratively yields _its original argument_ and the
55
+ # _IDs_ of the argument property's sub properties to that block.
56
+ def self.relation_and_all_subproperties(predicate_id, &block)
57
+ yield predicate_id
58
+
59
+ spo_id = Item.find_by_name("sub_property_of").id
60
+ connections = Connection.all( :conditions => [
61
+ "predicate_id = ? AND obj_id = ?", spo_id, predicate_id ])
62
+ connections.each do |e|
63
+ relation_and_all_subproperties(e.subject_id, &block)
64
+ end
65
+ end
66
+
67
+ # This method tests for chains of relationships between
68
+ # PropertyItem's. Its parameters are packaged in a single hash
69
+ # argument. The value of each entry in the hash is the _ID_ of an
70
+ # Item in the database. It returns a boolean that answers the
71
+ # "question" phrased in the parameter hash.
72
+ #
73
+ # Currently, there are two supported combinations of argument
74
+ # symbols:
75
+ #
76
+ # * <tt>:does</tt> xxxx <tt>:inherit_from</tt> xxxx <tt>:via</tt> xxxx
77
+ # * <tt>:does</tt> xxxx <tt>:link_to</tt> xxxx <tt>:through_children_of</tt> xxxx
78
+ #
79
+ # Both of these combinations form a question, the answer to which is
80
+ # in the boolean returned by this method (+true+ for yes). The
81
+ # symbols used to index the argument hash are:
82
+ #
83
+ # [:does] The value in the hash associated with <tt>:does</tt> is the ID of the Item for which the caller is querying the connections stored in the database.
84
+ # [:inherit_from] The value in the hash associated with <tt>:inherit_from</tt> is the ID of a PropertyItem (different from the <tt>:does</tt> Item) in the database. check_properties() will test for the presence of specific connections between this PropertyItem and the one specified by <tt>:does</tt>.
85
+ # [:via] The value in the hash associated with <tt>:via</tt> is the ID of the PropertyItem that must be present as the predicate of a connection for that connection to "count" toward establishing a chain of connections from the <tt>:does</tt> item to the <tt>:inherit_from</tt> item. Note that <tt>:via</tt> is directional: When <tt>:inherit_from</tt> is used, only connections where the <tt>:does</tt> item is the subject, the <tt>:inherit_from</tt> is the object, and all intervening connections "point" in that same direction will be tested, and this method will return <tt>true</tt> only when a chain of connections using the <tt>:via</tt> PropertyItem as their predicates can be found.
86
+ # [:link_to] The value in the hash associated with <tt>:link_to</tt> is the ID of another Item, to which check_properties will try to find a chain of connections from the <tt>:does</tt> Item. Note that unlike calls to check_properties using <tt>:inherit_from</tt>, when <tt>:link_to</tt> is used the starting and ending items can be of any type, not just PropertyItems.
87
+ # [:through_children_of] The value in the hash associated with <tt>:through_children_of</tt> is the ID of a PropertyItem. check_properties attempts to find a chain of connections between the other two Item parameters (in either direction) where the connections use the <tt>:through_children_of</tt> PropertyItem _or_ any PropertyItem that is a _child_ of the specified PropertyItem through the built-in <tt>sub_property_of</tt> relationship. Unlike calls using <tt>:inherit_from</tt>, when checking <tt>:link_to</tt> connections present in either direction between the items found in a chain can produce a <tt>true</tt> result.
88
+ def self.check_properties(hash_of_params)
89
+ unless hash_of_params.has_key?(:does)
90
+ raise ArgumentError, "Expected :does in input hash"
91
+ end
92
+
93
+ if hash_of_params.has_key?(:inherit_from)
94
+ # TODO: ':via' is *almost* always a reference to
95
+ # sub_property_of. Change this method and refactor callers so
96
+ # that when :via isn't present, it defaults to s_p_o. (If we
97
+ # keep asking ActiveRecord to find_by_name(s_p_o), will it be
98
+ # cached or a huge performance hit? Experiment and if
99
+ # A.R. really goes to the database each time, have a static
100
+ # variable here so that we only have to fetch from the db the
101
+ # first time.)
102
+ unless hash_of_params.has_key?(:via)
103
+ raise ArgumentError, "Expected :via in input hash"
104
+ end
105
+
106
+ child_id = hash_of_params[:does]
107
+ parent_id = hash_of_params[:inherit_from]
108
+ via_property_id = hash_of_params[:via]
109
+ # treat "self" as a form of inheritence
110
+ if child_id == parent_id
111
+ return true
112
+ end
113
+
114
+ connections = Connection.all( :conditions => [
115
+ "subject_id = ? AND predicate_id = ?", child_id, via_property_id ])
116
+ connections.each do |e|
117
+ if check_properties(
118
+ :does => e.obj_id,
119
+ :inherit_from => parent_id,
120
+ :via => via_property_id )
121
+ return true
122
+ end
123
+ end
124
+ elsif hash_of_params.has_key?(:link_to)
125
+ unless hash_of_params.has_key?(:through_children_of)
126
+ raise ArgumentError, "Expected :through_children_of in input hash"
127
+ end
128
+
129
+ from_item_id = hash_of_params[:does]
130
+ to_item_id = hash_of_params[:link_to]
131
+ kind_of_path = hash_of_params[:through_children_of]
132
+ spo_id = Item.find_by_name("sub_property_of").id
133
+
134
+ connections = Connection.all( :conditions =>
135
+ [ "subject_id = ?", from_item_id ])
136
+ connections.each do |e|
137
+ if check_properties(
138
+ :does => e.predicate_id,
139
+ :inherit_from => kind_of_path,
140
+ :via => spo_id )
141
+ if e.obj_id == to_item_id
142
+ return true
143
+ else
144
+ if check_properties(
145
+ :does => e.obj_id,
146
+ :link_to => to_item_id,
147
+ :through_children_of => kind_of_path )
148
+ return true
149
+ end
150
+ end
151
+ end
152
+ end
153
+ else
154
+ raise ArgumentError, "Expected :inherit_from or :link_to in input hash"
155
+ end
156
+ return false
157
+ end
158
+ end