wontomedia 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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