Compare commits

...

54 Commits

Author SHA1 Message Date
4dcc1b0e04 Made persistence design more flexible, and no requirement on mysql by default. 2015-01-19 19:20:42 +01:00
db9e40cec4 Updated CMS_SERVICE to make the cms library complete void-safe.
Reviewed configuration related feature.
Renamed JSON_CONFIGURATION as APPLICATION_JSON_CONFIGURATION_HELPER to avoid confusion.
Updated CMS_DEFAULT_SETUP to use configuration from cms configuration library.
Added {CMS_API}.module_configuration (a_module_name: READABLE_STRING_GENERAL; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER  to help getting access to configuration of a module (for now, only json and ini are supported, but in the future, this could support database layer directly)
Added CMS_HOOK_BLOCK_HELPER to reuse the template_block (..): ... function.
Cosmetic
Removed CMS_SETUP.smtp_server since for now, there is no need for such general setting.
Add header line "X-ServerEWF-App: CMS" as a simple way to know if request is processed by the CMS.
2015-01-14 18:25:26 +01:00
Javier Velilla
792880aa7a Update Module implementation 2015-01-02 10:43:17 -03:00
Javier Velilla
5ad8c680a6 Add your own Module 2014-12-31 08:06:54 -03:00
jvelilla
e2f02953f4 Refactor rename error_500_cms_response to internal_server_error_cms_response
Added bad_request_error_cms_response
Updated code example to use the new internal_server_error_cms_response instead of error_500_cms_response class.
Removed class error_500_cms_response.

Updated cms setup and configuration design:
  Removed CMS_SETUP.configuration: CMS_CONFIGURATION
  Removed CMS_CONFIGURATION and replaced it by using the configuration library.
  Added CMS_DEFAULT_SETUP.configuration: CONFIG_READER
  Addec CMS_SETUP.text_item (name): detachable READABLE_STRING_32 ...
    in order to access option not publish by the CMS_SETUP interface.
Removed CMS_SERVICE.configuration: CMS_CONFIGURATION since it was not used.

Moved configuration library from eiffel-lang to cms libraries.
Fixed issue related to ini config when parsing from string content,
  and also issue related to section included in file via @include.
Updated cms setup and configuration design:
  Removed CMS_SETUP.configuration: CMS_CONFIGURATION
  Removed CMS_CONFIGURATION and replaced it by using the configuration library.
  Added CMS_DEFAULT_SETUP.configuration: CONFIG_READER
  Addec CMS_SETUP.text_item (name): detachable READABLE_STRING_32 ...
    in order to access option not publish by the CMS_SETUP interface.
Removed CMS_SERVICE.configuration: CMS_CONFIGURATION since it was not used.
Improved the email service and related.
2014-12-19 18:03:52 -03:00
jvelilla
bd26deb6c1 Updated cms configuration file with an smtp server property.
Updated cms code to use the new property.
Removed title from the home response.
2014-12-17 09:16:19 -03:00
jvelilla
a9109ca8f7 Updated CMS_SMARTY_TEMPALTE_BLOCK, redefined out to be used by the logger.
Updated CMS_API, added wrapper features to access error_handler. has_error, reset, as_string_representation, hide
the actual error hanlder implementation.
Updated Error Filter with better logging.
2014-11-26 13:57:04 -03:00
09e5dc4032 Removed a few obsolete calls related to JSON library.
+ cosmetic
2014-11-20 15:14:34 +01:00
d082326784 Removed useless CMS_CUSTOM_SETUP. 2014-11-20 14:57:19 +01:00
51462829c7 reverted renaming to use `modules' for available modules.
Added CMS_SETUP.register_module (m) to avoid extending directly to the CMS_SETUP.modules
2014-11-20 14:53:54 +01:00
ba58fcdf75 Updated cms library with comments, and removed a few JSON obsolete calls. 2014-11-20 14:11:28 +01:00
Javier Velilla
d84f164dbd Update concepts.md
Updated concepts
2014-11-19 13:20:53 -03:00
jvelilla
c3d022ce46 Refactor raname {CMS_SETUP}.modules as {CMS_SETUP}.available_modules
Refactor raname {CMS_SETUP}.modules_enabled as {CMS_SETUP}.enabled_modules
Updated code to use the new features names.
2014-11-19 13:20:07 -03:00
jvelilla
aac01e093a Added {CMS_SETUP}.modules_enabled: CMS_MODULE_COLLECTION
Updated {CMS_SERVIDE}.intialize_modules to use the new feature {CMS_SETUP}.modules_enabled
Updated cms_hook_block description
2014-11-19 12:13:07 -03:00
jvelilla
fb62a1bb3e Merge branch 'roc_template' of https://github.com/jvelilla/ROC into roc_template 2014-11-19 11:50:56 -03:00
Javier Velilla
6162432d52 Update concepts.md
Updated Concepts table of contents
2014-11-19 11:32:59 -03:00
Javier Velilla
ebed52ae01 Update concepts.md
Updated concepts with Modules and Hooks
2014-11-19 11:16:02 -03:00
b58eeeac26 Added comments. 2014-11-19 13:34:42 +01:00
jvelilla
9169bdcd43 Removed shared_error from CMS_API
Added Missing theme and Missing tempalte classes.
Updated CMS_RESPONSE to handle missing template and send a 503 status code
with a raw response.
2014-11-19 09:22:31 -03:00
jvelilla
e36465f86d Update concepts.md
Added references to the important classes.
2014-11-18 09:26:52 -03:00
76190de218 Fixed non void-safe compilations, and cleaned .ecf files.
+Cosmetic
2014-11-18 10:05:50 +01:00
jvelilla
0edff7853b Removed default_theme.
Update theme and smarty theme description
2014-11-17 22:37:10 -03:00
jvelilla
e20a7af301 Merge pull request #15 from jvelilla/roc_template
Roc template
2014-11-17 13:08:33 -03:00
jvelilla
089b367c95 Update concepts.md
Updated default regions
2014-11-17 13:08:01 -03:00
jvelilla
503f2faf08 Update concepts.md
Updated
2014-11-17 13:03:13 -03:00
jvelilla
b887c13664 Renamed files and added tutorial document 2014-11-17 12:44:37 -03:00
jvelilla
bbfe063b5c Update CMS_concepts.md
Added table of contents
2014-11-17 12:26:58 -03:00
jvelilla
1a4e2935da Update README.md
Update readme file
2014-11-17 12:23:37 -03:00
jvelilla
c3a582f85c Added cms_concepts 2014-11-17 12:10:51 -03:00
8bfb66af30 Added cms_smarty_template_block
Added CMS_RESPONSE.module_assets_location and CMS_RESPONSE.module_assets_theme_location
    that help locating module related assets.
Added CMS_BLOCK.is_raw to abstract CMS_CONTENT_BLOCK.is_raw
2014-11-14 19:31:40 +01:00
6aad460b11 Updated ecf files, and added non void-safe .ecf files. 2014-11-14 14:20:01 +01:00
jvelilla
0dc12b82b8 Merge pull request #14 from jvelilla/roc_template
Update sqlite implemenation to make it compile
2014-11-14 08:26:06 -03:00
jvelilla
8047880c2b Update sqlite implemenation to make it compile 2014-11-13 23:46:02 -03:00
jvelilla
48283742aa Merge pull request #13 from jocelyn/minor_changes_20141113
Renamed {CMS_SETUP} theme_resource_location as theme_assets_location
2014-11-13 15:28:39 -03:00
76bdbeaa2a Renamed {CMS_SETUP} theme_resource_location as theme_assets_location
Added missing known hook in auto register hook.
Implemented /theme/* file system response.
Implemented $page.type for the smarty template.
Added CMS_DEBUG_MODULE .
Added NOT_FOUND_ERROR_CMS_RESPONSE .
2014-11-13 19:25:01 +01:00
Jocelyn Fiat
44a1dd62cb Merge pull request #12 from jvelilla/roc_template
Refactor directory structrue	d963fd2
Fixed typo in readme.md
2014-11-13 16:10:40 +01:00
jvelilla
1f8be4e37f Fixed typo in readme.md 2014-11-13 11:59:14 -03:00
jvelilla
d963fd218b Refactor directory structrue 2014-11-13 11:57:36 -03:00
Jocelyn Fiat
8ab4343d5b Merge pull request #11 from jvelilla/roc_template
Added README documentation.
Renamed examples/roc_api to demo.
Added contracts
2014-11-13 14:57:46 +01:00
jvelilla
9af6356f0a Added README doc.
Renamed example/roc_api to demo.
Added contracts
2014-11-13 10:50:54 -03:00
jvelilla
b16048eb18 Merge pull request #10 from jocelyn/copyright_20141113
Added copyright, note, and minor improvements.
2014-11-13 09:00:21 -03:00
71734a6dd7 Renamed model-safe.ecf as cms_model-safe.ecf since it is very specific to the cms.
Fixed compilation issue due to recent use of STRING_TABLE.
2014-11-13 11:15:35 +01:00
9cd53c7c78 updated readme. 2014-11-13 10:53:57 +01:00
a51d0d3c68 Added copyright, various description notes.
Added CMS_EXTERNAL_LINK, and improve various link interfaces.
Structured the model library with sub folder: user, link and content.
2014-11-13 10:50:22 +01:00
jvelilla
b3c2879b07 Merge pull request #9 from jocelyn/auto_hook_20141112
Restored implementation for auto register hooks.
2014-11-12 22:37:30 -03:00
e1feee51f9 Restore implementation for auto register hooks. 2014-11-12 22:35:24 +01:00
Jocelyn Fiat
2aaed89417 Merge pull request #8 from jvelilla/roc_template
Move libraries `layout', `model', `peristence' under cms folder
2014-11-12 21:55:25 +01:00
jvelilla
789b26eafa Move libraries layout', model', `peristence' under cms folder
Updated code to the new layout.
Added missing comments.
Remove /example/api
2014-11-12 17:24:34 -03:00
jvelilla
a576c38d42 Merge pull request #7 from jocelyn/cosmetic_20141112
Cosmetic 20141112
2014-11-12 13:19:59 -03:00
a524b80108 Made CMS_SETUP.site_url detachable.
Cosmetic, avoid long lines of comments.
Added debug ("refactor_fixme") around a few REFACTORING_HELPER.fixme (...)
Better message for a few fixme(...) related to unimplemented routines.
2014-11-12 17:13:18 +01:00
48a8ac4a1c First step toward more generic way to handle hook subscribers. 2014-11-12 16:53:42 +01:00
Jocelyn Fiat
1d4e9df917 Merge pull request #6 from jvelilla/roc_template
Updated Descriptions to classes and features
2014-11-12 16:51:23 +01:00
jvelilla
2d5c1a5e41 Updated Descriptions to classes and features 2014-11-12 12:30:09 -03:00
jvelilla
fba9b598f9 Merge pull request #5 from jocelyn/hook_20141112
name changes related to CMS HOOK and callers.
2014-11-12 12:27:00 -03:00
317 changed files with 3912 additions and 12346 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
EIFGENs
*.swp
*.log*
*.rc
*.rc
*.bak

34
README.md Normal file
View File

@@ -0,0 +1,34 @@
Eiffel CMS Library
===============
Eiffel CMS library is build with [EWF](http://eiffelwebframework.github.io/EWF/) and inspired by [Drupal](https://www.drupal.org/).
The goal of the library is to provide the following features.
- content type
- user management
- module design
- theme
- API
**Directory Structure**
- library --Library
- layout -- application layout library.
- model -- domain model library.
- persistence -- persistence layer library.
- src -- cms source code.
- example
- demo -- example using the cms library.
- doc -- Documentation.
**Documentation**
>[CMS concepts](/doc/concepts.md).
>[CMS design](/doc/design.md).
>[CMS tutorial](/doc/tutorial.md).

View File

@@ -2,27 +2,26 @@
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms">
<root all_classes="true"/>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="config" location=".\library\configuration\config-safe.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location="..\layout\layout-safe.ecf"/>
<library name="model" location="..\model\model-safe.ecf" readonly="false"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="persistence_mysql" location="..\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location=".\library\layout\layout-safe.ecf"/>
<library name="model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
<cluster name="src" location=".\library\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>

33
cms.ecf Normal file
View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms">
<root all_classes="true"/>
<option warning="true" full_class_checking="false" void_safety="none" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="config" location=".\library\configuration\config.ecf"/>
<library name="layout" location=".\library\layout\layout.ecf"/>
<library name="model" location=".\library\model\cms_model.ecf" readonly="false"/>
<library name="persistence_mysql" location=".\library\persistence\implementation\mysql\persistence_mysql.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf" readonly="false"/>
<cluster name="src" location=".\library\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -1,294 +0,0 @@
class
CMS_CONFIGURATION
inherit
ANY
SHARED_EXECUTION_ENVIRONMENT
export
{NONE} all
end
create
make
feature {NONE} -- Initialization
make (a_layout: CMS_LAYOUT)
-- Initialize `Current'.
do
layout := a_layout
create options.make_equal (10)
configuration_location := layout.cms_config_ini_path
import_from_path (layout.cms_config_ini_path)
analyze
end
analyze
do
get_root_location
get_var_location
get_themes_location
get_files_location
end
feature -- Access
configuration_location: detachable PATH
option (a_name: READABLE_STRING_GENERAL): detachable ANY
do
Result := options.item (a_name)
end
options: STRING_TABLE [STRING_32]
feature -- Conversion
append_to_string (s: STRING)
local
utf: UTF_CONVERTER
do
s.append ("Options:%N")
across
options as c
loop
s.append (c.key.to_string_8)
s.append_character ('=')
utf.string_32_into_utf_8_string_8 (c.item, s)
s.append_character ('%N')
end
s.append ("Specific:%N")
s.append ("root_location=" + root_location.utf_8_name + "%N")
s.append ("var_location=" + var_location.utf_8_name + "%N")
s.append ("files_location=" + files_location.utf_8_name + "%N")
s.append ("themes_location=" + themes_location.utf_8_name + "%N")
end
feature -- Element change
set_option (a_name: READABLE_STRING_GENERAL; a_value: STRING_32)
do
options.force (a_value, a_name.as_string_8)
end
feature -- Access
var_location: PATH
root_location: PATH
files_location: PATH
themes_location: PATH
theme_name (dft: detachable like theme_name): READABLE_STRING_8
do
if attached options.item ("theme") as s then
Result := s
elseif dft /= Void then
Result := dft
else
Result := "default"
end
end
site_id: READABLE_STRING_8
do
if attached options.item ("site.id") as s then
Result := s
else
Result := "_EWF_CMS_NO_ID_"
end
end
site_name (dft: like site_name): READABLE_STRING_8
do
if attached options.item ("site.name") as s then
Result := s
else
Result := dft
end
end
site_url (dft: like site_url): READABLE_STRING_8
do
if attached options.item ("site.url") as s then
Result := s
else
Result := dft
end
if Result /= Void then
if Result.is_empty then
-- ok
elseif not Result.ends_with ("/") then
Result := Result + "/"
end
end
end
site_script_url (dft: like site_script_url): detachable READABLE_STRING_8
do
if attached options.item ("site.script_url") as s then
Result := s
else
Result := dft
end
if Result /= Void then
if Result.is_empty then
elseif not Result.ends_with ("/") then
Result := Result + "/"
end
end
end
site_email (dft: like site_email): READABLE_STRING_8
do
if attached options.item ("site.email") as s then
Result := s
else
Result := dft
end
end
feature -- Change
get_var_location
local
utf: UTF_CONVERTER
do
if attached options.item ("var-dir") as s then
create var_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
else
var_location := execution_environment.current_working_path
end
end
get_root_location
do
root_location := layout.www_path
end
get_files_location
local
utf: UTF_CONVERTER
do
if attached options.item ("files-dir") as s then
create files_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
else
create files_location.make_from_string ("files")
end
end
get_themes_location
local
utf: UTF_CONVERTER
do
if attached options.item ("themes-dir") as s then
create themes_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
else
themes_location := root_location.extended ("themes")
end
end
feature {NONE} -- Implementation
import_from_file (fn: READABLE_STRING_GENERAL)
do
import_from_path (create {PATH}.make_from_string (fn))
end
import_from_path (a_filename: PATH)
-- Import ini file content
local
f: PLAIN_TEXT_FILE
l,v: STRING_8
p: INTEGER
do
create f.make_with_path (a_filename)
if f.exists and f.is_readable then
f.open_read
from
f.read_line
until
f.exhausted
loop
l := f.last_string
l.left_adjust
if not l.is_empty then
if l[1] = '#' then
-- commented line
else
p := l.index_of ('=', 1)
if p > 1 then
v := l.substring (p + 1, l.count)
l.keep_head (p - 1)
v.left_adjust
v.right_adjust
l.right_adjust
if l.is_case_insensitive_equal ("@include") then
import_from_file (resolved_string (v))
else
set_option (l.as_lower, resolved_string (v))
end
end
end
end
f.read_line
end
f.close
end
end
feature {NONE} -- Environment
resolved_string (s: READABLE_STRING_8): STRING_32
-- Resolved `s' using `options' or else environment variables.
local
i,n,b,e: INTEGER
k: detachable READABLE_STRING_8
do
from
i := 1
n := s.count
create Result.make (s.count)
until
i > n
loop
if i + 1 < n and then s[i] = '$' and then s[i+1] = '{' then
b := i + 2
e := s.index_of ('}', b) - 1
if e > 0 then
k := s.substring (b, e)
if attached option (k) as v then
if attached {READABLE_STRING_32} v as s32 then
Result.append (s32)
else
Result.append (v.out)
end
i := e + 1
elseif attached execution_environment.item (k) as v then
Result.append (v)
i := e + 1
else
Result.extend (s[i])
end
else
Result.extend (s[i])
end
else
Result.extend (s[i])
end
i := i + 1
end
end
feature -- Implementation
layout: CMS_LAYOUT
-- Cms layout
end

View File

@@ -1,15 +0,0 @@
note
description: "Summary description for {CMS_CUSTOM_SETUP}."
date: "$Date$"
revision: "$Revision$"
class
CMS_CUSTOM_SETUP
inherit
CMS_DEFAULT_SETUP
create
make
end

View File

@@ -1,110 +0,0 @@
note
description: "Summary description for {CMS_DEFAULT_SETUP}."
date: "$Date$"
revision: "$Revision$"
class
CMS_DEFAULT_SETUP
inherit
CMS_SETUP
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make (a_layout: CMS_LAYOUT)
do
layout := a_layout
create configuration.make (layout)
initialize
end
initialize
do
configure
create modules.make (3)
build_mailer
initialize_modules
end
configure
do
site_id := configuration.site_id
site_url := configuration.site_url ("")
site_name := configuration.site_name ("EWF::CMS")
site_email := configuration.site_email ("webmaster")
site_dir := configuration.root_location
site_var_dir := configuration.var_location
files_location := configuration.files_location
themes_location := configuration.themes_location
theme_name := configuration.theme_name ("default")
compute_theme_location
compute_theme_resource_location
end
initialize_modules
local
m: CMS_MODULE
do
-- -- Core
-- create {USER_MODULE} m.make (Current)
-- m.enable
-- modules.extend (m)
-- create {ADMIN_MODULE} m.make (Current)
-- m.enable
-- modules.extend (m)
create {NODE_MODULE} m.make (Current)
m.enable
modules.extend (m)
end
feature -- Access
modules: CMS_MODULE_COLLECTION
-- <Precursor>
is_html: BOOLEAN
-- <Precursor>
do
-- Enable change the mode
Result := (create {CMS_JSON_CONFIGURATION}).is_html_mode(layout.application_config_path)
end
is_web: BOOLEAN
-- <Precursor>
do
Result := (create {CMS_JSON_CONFIGURATION}).is_web_mode(layout.application_config_path)
end
build_auth_engine
do
to_implement ("Not implemented authentication")
end
build_mailer
do
to_implement ("Not implemented mailer")
end
feature -- Compute location
compute_theme_location
do
theme_location := themes_location.extended (theme_name)
end
compute_theme_resource_location
-- assets (js, css, images, etc)
-- Not used at the moment.
do
theme_resource_location := theme_location
end
end

View File

@@ -1,47 +0,0 @@
note
description: "Summary description for {CMS_JSON_CONFIGURATION}."
date: "$Date$"
revision: "$Revision$"
class
CMS_JSON_CONFIGURATION
inherit
JSON_CONFIGURATION
feature -- Access
is_html_mode (a_path: PATH): BOOLEAN
-- Is the server running on web mode?
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("server") as l_server and then
attached {JSON_STRING} l_server.item ("mode") as l_mode then
Result := l_mode.item.is_case_insensitive_equal_general ("html")
end
end
end
is_web_mode (a_path: PATH): BOOLEAN
-- Is the server running on web mode?
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("server") as l_server and then
attached {JSON_STRING} l_server.item ("mode") as l_mode then
Result := l_mode.item.is_case_insensitive_equal_general ("web")
end
end
end
end

View File

@@ -1,70 +0,0 @@
note
description: "Summary description for {CMS_SETUP}."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_SETUP
feature -- Access
configuration: CMS_CONFIGURATION
-- cms configuration.
layout: CMS_LAYOUT
-- CMS layout.
is_html: BOOLEAN
-- api with progressive enhancements css and js, server side rendering.
deferred
end
is_web: BOOLEAN
-- web: Web Site with progressive enhancements css and js and Ajax calls.
deferred
end
modules: CMS_MODULE_COLLECTION
-- List of available modules.
deferred
end
feature -- Access: Site
site_id: READABLE_STRING_8
site_name: READABLE_STRING_32
site_email: READABLE_STRING_8
site_url: READABLE_STRING_8
site_dir: PATH
site_var_dir: PATH
files_location: PATH
front_page_path: detachable READABLE_STRING_8
-- Optional path defining the front page.
-- By default "" or "/".
feature -- Access: Theme
themes_location: PATH
theme_location: PATH
theme_resource_location: PATH
--
theme_information_location: PATH
-- theme informations.
do
Result := theme_location.extended ("theme.info")
end
theme_name: READABLE_STRING_32
-- theme name
end

View File

@@ -1,177 +0,0 @@
note
description: "Summary description for {CMS_API}."
date: "$Date$"
revision: "$Revision$"
class
CMS_API
inherit
SHARED_ERROR
REFACTORING_HELPER
create
make
feature -- Initialize
make (a_setup: CMS_SETUP)
-- Create the API service with an storege `a_storage'.
do
setup := a_setup
create error_handler.make
initialize
set_successful
ensure
-- storage_set: storage = a_storage
end
setup: CMS_SETUP
-- CMS setup.
initialize
local
l_database: DATABASE_CONNECTION
retried: BOOLEAN
l_message: STRING
do
if not retried then
to_implement ("Refactor database setup")
if attached (create {JSON_CONFIGURATION}).new_database_configuration (setup.layout.application_config_path) as l_database_config then
create {DATABASE_CONNECTION_MYSQL} l_database.login_with_connection_string (l_database_config.connection_string)
create {CMS_STORAGE_MYSQL} storage.make (l_database)
else
create {DATABASE_CONNECTION_NULL} l_database.make_common
create {CMS_STORAGE_NULL} storage
end
else
to_implement ("Workaround code, persistence layer does not implement yet this kind of error handling.")
-- error hanling.
create {DATABASE_CONNECTION_NULL} l_database.make_common
create {CMS_STORAGE_NULL} storage
create l_message.make (1024)
if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then
if attached l_exception.description as l_description then
l_message.append (l_description.as_string_32)
l_message.append ("%N%N")
elseif attached l_exception.trace as l_trace then
l_message.append (l_trace)
l_message.append ("%N%N")
else
l_message.append (l_exception.out)
l_message.append ("%N%N")
end
else
l_message.append ("The application crash without available information")
l_message.append ("%N%N")
end
error_handler.add_custom_error (0, " Database Connection ", l_message)
end
rescue
retried := True
retry
end
feature -- Access
error_handler: ERROR_HANDLER
-- Error handler.
feature -- Status Report
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
do
Result := storage.is_valid_credential (l_auth_login, l_auth_password)
end
feature -- Access: Node
nodes: LIST[CMS_NODE]
-- List of nodes.
do
fixme ("Implementation")
Result := storage.recent_nodes (0, 10)
end
recent_nodes (a_offset, a_rows: INTEGER): LIST[CMS_NODE]
-- List of the `a_rows' most recent nodes starting from `a_offset'.
do
Result := storage.recent_nodes (a_offset, a_rows)
end
node (a_id: INTEGER_64): detachable CMS_NODE
-- Node by ID.
do
fixme ("Check preconditions")
Result := storage.node (a_id)
end
feature -- Change: Node
new_node (a_node: CMS_NODE)
-- Add a new node
do
storage.save_node (a_node)
end
delete_node (a_id: INTEGER_64)
do
storage.delete_node (a_id)
end
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
do
storage.update_node (a_id,a_node)
end
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
do
fixme ("Check preconditions")
storage.update_node_title (a_id,a_node_id,a_title)
end
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
do
fixme ("Check preconditions")
storage.update_node_summary (a_id,a_node_id, a_summary)
end
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
do
fixme ("Check preconditions")
storage.update_node_content (a_id,a_node_id, a_content)
end
feature -- Access: User
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
do
Result := storage.user_by_name (a_username)
end
feature -- Change User
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
do
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
storage.save_user (a_user)
else
fixme ("Add error")
end
end
feature {NONE} -- Implemenataion
storage: CMS_STORAGE
-- Persistence storage
end

View File

@@ -1,33 +0,0 @@
note
description: "Summary description for {CMS_ERROR_FILTER}."
date: "$Date$"
revision: "$Revision$"
class
CMS_ERROR_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
CMS_HANDLER
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter
do
if not api.error_handler.has_error then
log.write_information (generator + ".execute")
execute_next (req, res)
else
log.write_critical (generator + ".execute" + api.error_handler.as_string_representation )
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
api.error_handler.reset
end
end
end

View File

@@ -1,100 +0,0 @@
note
description: "Summary description for {CMS_HTML_TEMPLATE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
DEFAULT_CMS_HTML_TEMPLATE
inherit
CMS_HTML_TEMPLATE
DEFAULT_CMS_TEMPLATE
create
make
feature {NONE} -- Initialization
make (t: DEFAULT_CMS_THEME)
do
theme := t
create variables.make (0)
end
variables: STRING_TABLE [detachable ANY]
feature -- Access
register (v: STRING_8; k: STRING_8)
do
variables.force (v, k)
end
theme: DEFAULT_CMS_THEME
prepare (page: CMS_HTML_PAGE)
do
variables.make (10)
across
page.variables as ic
loop
variables.force (ic.item, ic.key)
end
if attached page.title as l_title then
variables.force (l_title, "title")
variables.force (l_title, "head_title")
else
variables.force ("", "title")
variables.force ("", "head_title")
end
variables.force (page.language, "language")
variables.force (page.head_lines_to_string, "head_lines")
end
to_html (page: CMS_HTML_PAGE): STRING
do
-- Process html generation
create Result.make_from_string (template)
apply_template_engine (Result)
end
feature {NONE} -- Implementation
template: STRING
once
Result := "[
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="$language" lang="$language" version="XHTML+RDFa 1.0" dir="ltr">
<head>
$head
<title>$head_title</title>
$styles
$scripts
$head_lines
</head>
<body class="$body_classes" $body_attributes>
$page_top
$page
$page_bottom
</body>
</html>
]"
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,102 +0,0 @@
note
description: "Summary description for {CMS_PAGE_TEMPLATE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
DEFAULT_CMS_PAGE_TEMPLATE
inherit
CMS_PAGE_TEMPLATE
DEFAULT_CMS_TEMPLATE
create
make
feature {NONE} -- Initialization
make (t: DEFAULT_CMS_THEME)
do
theme := t
create variables.make (0)
end
variables: STRING_TABLE [detachable ANY]
feature -- Access
theme: DEFAULT_CMS_THEME
prepare (page: CMS_HTML_PAGE)
do
variables.make (10)
across
page.variables as ic
loop
variables.force (ic.item, ic.key)
end
if attached page.title as l_title then
variables.force (l_title, "title")
else
variables.force ("", "title")
end
across
theme.regions as r
loop
variables.force (page.region (r.item), r.item)
end
end
to_html (page: CMS_HTML_PAGE): STRING
do
-- Process html generation
create Result.make_from_string (template)
apply_template_engine (Result)
end
feature -- Registration
register (v: STRING_8; k: STRING_8)
do
variables.force (v, k)
end
feature {NONE} -- Implementation
template: STRING
once
Result := "[
<div id="page-wrapper">
<div id="page">
<div id="header">
$header
</div>
<div id="main-wrapper">
<div id="main">
<div id="first_sidebar" class="sidebar $first_sidebar_css_class">$first_sidebar</div>
<div id="content" class="$content_css_class">$content</div>
<div id="second_sidebar" class="sidebar $second_sidebar_css_class">$second_sidebar</div>
</div>
</div>
<div id="footer">$footer</div>
</div>
</div>
]"
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,100 +0,0 @@
note
description: "Summary description for {CMS_THEME}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
DEFAULT_CMS_THEME
inherit
CMS_THEME
create
make
feature {NONE} -- Initialization
make (a_setup: like setup; a_info: like information)
do
setup := a_setup
information := a_info
end
information: CMS_THEME_INFORMATION
feature -- Access
name: STRING = "CMS"
regions: ARRAY [STRING]
once
Result := <<"header", "content", "footer", "first_sidebar", "second_sidebar">>
end
html_template: DEFAULT_CMS_HTML_TEMPLATE
local
tpl: like internal_html_template
do
tpl := internal_html_template
if tpl = Void then
create tpl.make (Current)
internal_html_template := tpl
end
Result := tpl
end
page_template: DEFAULT_CMS_PAGE_TEMPLATE
local
tpl: like internal_page_template
do
tpl := internal_page_template
if tpl = Void then
create tpl.make (Current)
internal_page_template := tpl
end
Result := tpl
end
feature -- Conversion
prepare (page: CMS_HTML_PAGE)
do
end
page_html (page: CMS_HTML_PAGE): STRING_8
local
l_content: STRING_8
do
prepare (page)
page_template.prepare (page)
l_content := page_template.to_html (page)
html_template.prepare (page)
html_template.register (l_content, "page")
Result := html_template.to_html (page)
end
navigation_template: detachable READABLE_STRING_GENERAL
-- navigation template name, if any.
do
end
feature {NONE} -- Internal
internal_page_template: detachable like page_template
internal_html_template: detachable like html_template
invariant
attached internal_page_template as inv_p implies inv_p.theme = Current
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

93
doc/concepts.md Normal file
View File

@@ -0,0 +1,93 @@
CMS Concepts
============
>Current implemented concepts
##### Table of Contents
1. [**Theme**](#theme)
2. [**Regions**](#regions)
- [**Default Page Layout**](#page_layout)
- [**Regions Holds blocks**](#regions_blocks)
3. [**Blocks**](#blocks)
4. [**Modules**](#modules)
5. [**Hooks**](#hooks)
<a name="theme"/>
Theme
-----
In a CMS , a theme is a collection of templates files (HTML, CSS, Images, etc ) that determine how a CMS web site looks. The goal of a theme is to let you change the look and feel of the site.
Eiffel CMS is inspired by Drupal, and use the same default region names as default drupal theme.
#### Important Classes
* [CMS_THEME] (/library/src/theme/cms_theme.e): Abstraction defining the interface of a CMS theme.
* [SMARTY_CMS_THEME] (/library/src/theme/smarty_theme/smarty_cms_theme.e): Theme implemented using the [Eiffel Smarty library] (https://github.com/eiffelhub/template-smarty).
* [CMS_TEMPLATE] (/library/src/theme/cms_template.e): Template Abstraction that contains theme, variables needed by template when rendering page as html. At the moment there is only one implementation SMARTY_CMS_PAGE_TEMPLATE. At the moment there is only one implementation [SMARTY_CMS_PAGE_TEMPLATE] (/library/src/theme/smarty_theme/smarty_cms_page_template.e).
<a name="regions"/>
Regions
-------
The layout of a CMS web page has predefined area called **regions**. The Eiffel CMS uses the same default regions as Drupal, so let's see them in the following image.
<a name="page_layout"/>
![default page layout](http://themery.com/sites/default/files/figure-15-10.png)
```
regions[page_top] = Top
regions[header] = Header
regions[content] = Content
regions[highlighted] = Highlighted
regions[help] = Help
regions[footer] = Footer
regions[first_sidebar] = first sidebar
regions[second_sidebar] = second sidebar
regions[page_bottom] = Bottom
```
<a name="regions_blocks"/>
**A Region holds blocks**
**What goes inside regions?**
Generally, regions hold smaller piece of content called blocks. Blocks hold chunks of content, like the user login form, navigation menu or the information for the footer.
Regions are defined in a configuration file theme.info.
<a name="blocks"/>
CMS_BLOCK
---------
**What is a cms block?**
Blocks are chunk of content that can be created to display whatever you want, and then can be placed in various resgions in your template (theme) layout.
#### Important Classes
* [CMS_BLOCK] (/library/src/kernel/content/cms_block.e): The deferred class CMS_BLOCK provides an abstraction to describe content to be placed inside Regions.
* [CMS_CONTENT_BLOCK] (/library/src/kernel/content/cms_content_block.e): The class CMS_CONTENT_BLOCK describe how to provide generic content.
* [CMS_MENU_BLOCK](/library/src/kernel/content/cms_menu_block.e): The class CMS_MENU_BLOCK describe how to provides a menu of navigational links.
* [CMS_SMARTY_TEMPLATE_BLOCK] (/library/src/kernel/content/cms_smarty_templateblock.e) The class CMS_SMARTY_TEMPLATE_BLOCK describe how to use a CMS block with smarty template file content.
<a name="modules"/>
CMS_MODULES
-----------
**What is a cms module?**
Modules are piece of code that adds one or more features to your web site.
Modules can be plugged and combined to provide a web site customized to your needs. There are modules for many purposes, for example Administratiton, Basic Authentication, etc.
#### Important Classes
* [CMS_MODULE] (/library/src/modules/cms_module.e): The deferred class CMS_MODULE provides an abstraction to describe a generic module that add features to your web site.
* [CMS_RESPONSE](/library/src/service/response/cms_response.e). The deferred class CMS_RESPONSE provide an abstraction to builds the content to get process to render the output.
<a name="hooks">
CMS_HOOK
--------
Hooks is a mechanism which provide a way for modules to interact with each other and extending blocks of the current CMS.
* [CMS_HOOK] (/library/src/hooks/cms_hook.e): The deferred class CMS_HOOK is a marker interface for CMS Hook
* [CMS_HOOK_AUTO_REGISTER] (/library/src/hooks/cms_hook_auto_register.e): The deferred class provides an abstraction that when inheriting from this class, the declared hooks are automatically registered, otherwise, each descendant has to add it to the cms service itself.
* [CMS_HOOK_BLOCK](/library/src/hooks/cms_hook_block.e): The class CMS_HOOK_BLOCK describe a hook providing a way to alter a generic block.
* [CMS_HOOK_FORM_ALTER](/library/src/hooks/cms_hook_form_alter.e): The class CMS_HOOK_FORM_ATLER describe a hook providing a way to alter a form.
* [CMS_HOOK_MENU_ALTER](/library/src/hooks/cms_hook_menu_alter.e): The class CMS_HOOK_MENU_ATLER describe a hook providing a way to alter a menu.
* [CMS_HOOK_MENU_SYSTEM_ALTER](/library/src/hooks/cms_hook_menu_system_alter.e): The class CMS_HOOK_MENU_SYSTEM_ALTER describe a hook providing a way to alter the CMS menu system.
* [CMS_HOOK_VALUE_TABLE_ALTER](/library/src/hooks/cms_hook_value_table_alter.e):: The class CMS_HOOK_VALUE_TABLE_ALTER describe a hook providing a way to alter the value table for a response.

121
doc/tutorial.md Normal file
View File

@@ -0,0 +1,121 @@
CMS Tutorial
============
[Work in progress]
##### Table of Contents
[Getting Started](#init)
[Building your module](#module)
[Lifecycle](#cycle)
<a name="init"/>
Getting Started
-------------
<a name="module"/>
Building your own module
------------------------
A [Module](/doc/concepts.md#modules) as we already describe it, enable us to add functionallity based on your needs.
Here we will describe the basics steps to write your own modules.
* The first thing to do is inherit from the class [CMS_MODULE] () and redefine the register_hooks (2) feature.
* Implement (via inheritance) the needed [Hooks] (/doc/concepts.md#hooks).
* Define the module API through route definition. (1)
* Define the list of block to be handle by the current module (3).
* Render the block (4) (could be defined in Eiffel itself or using a template file (smarty)).
* API implementation (5).
```
class MY_NEW_MODULE
inherit
CMS_MODULE
redefine
register_hooks
end
CMS_HOOK_BLOCK
CMS_HOOK_MENU_SYSTEM_ALTER
create
make
feature {NONE} -- Initialization
make
-- Create current module
do
name := "new module"
version := "1.0"
description := "Eiffel new module"
package := "example"
end
feature -- Access: router
router (a_api: CMS_API): WSF_ROUTER
-- (1) Node router.
do
create Result.make (1)
Result.handle_with_request_methods ("/demo", create {WSF_URI_AGENT_HANDLER}.make (agent handle_demo (a_api, ?, ?)), Result.methods_head_get)
end
feature -- Hooks
register_hooks (a_response: CMS_RESPONSE)
do
-- (2)
a_response.subscribe_to_menu_system_alter_hook (Current)
a_response.subscribe_to_block_hook (Current)
end
block_list: ITERABLE [like {CMS_BLOCK}.name]
do
-- (3) List of block names, managed by current object.
end
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
do
-- (4) Get block object identified by `a_block_id' and associate with `a_response'.
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
do
create lnk.make ("Demo", "/demo/")
a_menu_system.primary_menu.extend (lnk)
end
feature -- Handler
handle_demo (a_api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE;)
local
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
do
-- (5)
create r.make (req, res, a_api)
r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...")
r.add_error_message ("NODE Module: not yet implemented")
r.execute
end
end
```
<a name="cycle"/>
Lifecycle
---------

View File

@@ -1,49 +0,0 @@
CMS Hypermedia API and Adaptive Web Design
============================================
A content management system is not a simple domain.
This example shows how to build a basic Hypermedia API for a CMS using HTML5 and progressive enhacement.
The idea is based on an existing [Eiffel CMS] (https://github.com/EiffelWebFramework/cms), the goal is learn the domain and create a new modular CMS.
Persistence
============
The current solution uses MySQL and only handle users and nodes concept.
Authentication/Authorization
============================
Basic Auth.
API features
============
There is no session.
The root uri:
shows Navigation and the possiblity to add a New Node (only for loggedin users).
shows a predefined number of nodes the `n' most recent nodes.
Guest users will be able to list all the nodes and view a particular node.
Logged in users.
Logged users are able to
Add a new node
Edit an existing node
Edit a node title
Edit a node summary
Edit a node content
Delete a node
Server Modes
============
api: HTML5 API
html: api with progresive enhacements css and js, server side rendering.
web: api with progresive enhacements css and js and Ajax calls.
References
1: http://codeartisan.blogspot.se/2012/07/using-html-as-media-type-for-your-api.html
2: https://github.com/gustafnk/combining-html-hypermedia-apis-and-adaptive-web-design

View File

@@ -1,24 +0,0 @@
note
description: "[
Effective class for APPLICATION_LAUNCHER_I
You can put modification in this class
]"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
APPLICATION_LAUNCHER
inherit
APPLICATION_LAUNCHER_I
feature -- Custom
is_console_output_supported: BOOLEAN
do
Result := False
end
end

View File

@@ -1,102 +0,0 @@
note
description: "[
Specific application launcher
DO NOT EDIT THIS CLASS
you can customize APPLICATION_LAUNCHER
]"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
deferred class
APPLICATION_LAUNCHER_I
inherit
SHARED_EXECUTION_ENVIRONMENT
feature -- Execution
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
-- nature: like launcher_nature
do
-- nature := launcher_nature
-- if nature = Void or else nature = nature_nino then
-- launch_nino (a_service, opts)
-- elseif nature = nature_cgi then
-- launch_cgi (a_service, opts)
-- elseif nature = nature_libfcgi then
launch_libfcgi (a_service, opts)
-- else
-- -- bye bye
-- (create {EXCEPTIONS}).die (-1)
-- end
end
feature {NONE} -- Access
launcher_nature: detachable READABLE_STRING_8
-- Initialize the launcher nature
-- either cgi, libfcgi, or nino.
--| We could extend with more connector if needed.
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
local
p: PATH
ext: detachable READABLE_STRING_32
do
create p.make_from_string (execution_environment.arguments.command_name)
if attached p.entry as l_entry then
ext := l_entry.extension
end
if ext /= Void then
if ext.same_string (nature_nino) then
Result := nature_nino
end
if ext.same_string (nature_cgi) then
Result := nature_cgi
end
if ext.same_string (nature_libfcgi) or else ext.same_string ("fcgi") then
Result := nature_libfcgi
end
end
end
feature {NONE} -- nino
nature_nino: STRING = "nino"
launch_nino (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_NINO_SERVICE_LAUNCHER
do
create launcher.make_and_launch (a_service, opts)
end
feature {NONE} -- cgi
nature_cgi: STRING = "cgi"
launch_cgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_CGI_SERVICE_LAUNCHER
do
create launcher.make_and_launch (a_service, opts)
end
feature {NONE} -- libfcgi
nature_libfcgi: STRING = "libfcgi"
launch_libfcgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_LIBFCGI_SERVICE_LAUNCHER
do
create launcher.make_and_launch (a_service, opts)
end
end

View File

@@ -1,54 +0,0 @@
note
description: "[
Effective class for APPLICATION_LAUNCHER_I
You can put modification in this class
]"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
APPLICATION_LAUNCHER
inherit
APPLICATION_LAUNCHER_I
SHARED_EXECUTION_ENVIRONMENT
feature -- Status Report
is_console_output_supported: BOOLEAN
do
Result := launcher_nature = nature_nino
end
feature {NONE} -- Initialization
launcher_nature: detachable READABLE_STRING_8
-- Initialize the launcher nature
-- either cgi, libfcgi, or nino.
--| We could extend with more connector if needed.
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
local
p: PATH
ext: detachable READABLE_STRING_32
do
create p.make_from_string (execution_environment.arguments.command_name)
if attached p.entry as l_entry then
ext := l_entry.extension
end
if ext /= Void then
if ext.same_string (nature_nino) then
Result := nature_nino
end
end
end
feature {NONE} -- nino
nature_nino: STRING = "nino"
end

View File

@@ -1,26 +0,0 @@
note
description: "[
Specific application launcher
DO NOT EDIT THIS CLASS
you can customize APPLICATION_LAUNCHER
]"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
deferred class
APPLICATION_LAUNCHER_I
feature -- Execution
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_SERVICE_LAUNCHER
do
create {WSF_DEFAULT_SERVICE_LAUNCHER} launcher.make_and_launch (a_service, opts)
end
end

View File

@@ -1,2 +0,0 @@
port=8088
#verbose=true

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="api" uuid="8B2873E9-8E2A-4490-8B6C-1122B579FD1D" library_target="api">
<target name="common" abstract="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
<debug name="esa" enabled="true"/>
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<setting name="exception_trace" value="true"/>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="conneg" location="$ISE_LIBRARY\contrib\library\network\protocol\content_negotiation\conneg-safe.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="persistence_mysql" location="..\..\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\layout\layout-safe.ecf"/>
<library name="model" location="..\..\model\model-safe.ecf" readonly="false"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target>
<target name="api_any" extends="common">
<root class="ROC_SERVER" feature="make_and_launch"/>
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>
<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="api_nino" extends="common">
<root class="ROC_SERVER" feature="make_and_launch"/>
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="api_cgi" extends="common">
<root class="ROC_SERVER" feature="make_and_launch"/>
<library name="default_cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\cgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="api_libfcgi" extends="common">
<root class="ROC_SERVER" feature="make_and_launch"/>
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>
<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf" readonly="false"/>
<library name="wgi_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\ewsgi\connectors\nino\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<!-- <target name="api_test" extends="common">
<root class="APPLICATION_TEST" feature="make"/>
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
<library name="ewsgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\ewsgi\ewsgi-safe.ecf" readonly="false">
<option>
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
</option>
</library>
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<library name="wgi_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\ewsgi\connectors\nino\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location="src\" recursive="true"/>
<cluster name="test" location="test\" recursive="true"/>
</target>
-->
<target name="api" extends="api_nino">
</target>
</system>

View File

@@ -1,27 +0,0 @@
<nav id="" class="navbar navbar-default navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="{$host/}" rel="home">Rest on CMS</a>
</div>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="nav navbar-nav">
<li class="ListOfNodes"><a title="Nodes" href="{$host/}/nodes" rel="node">List of Nodes</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{if isset="$user"}
<li><a>{$user/}</a></li>
<li><a title="Node" href="{$host/}/node" rel="node">New Node</a></li>
<li><a title="Logoff" href="{$host/}/logoff" rel="logoff">Logoff</a></li>
{/if}
{unless isset="$user"}
<li><a title="Login" href="{$host/}/login" rel="login">Login</a></li>
<li><a title="Register" href="{$host/}/user" rel="register">Register</a></li>
{/unless}
</ul>
</div>
</div>
</nav>

View File

@@ -1,174 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="bs-docs-example">
{if condition="$web"}
<ul id="myTab" class="nav nav-tabs" role="tablist">
<li class=""><a href="#view" role="tab" data-toggle="tab">View</a></li>
<li class="active"><a href="#edit" role="tab" data-toggle="tab">Edit</a></li>
<li class=""><a href="#delete" role="tab" data-toggle="tab">Delete</a></li>
</ul>
{/if}
{if condition="$html"}
<ul id="myTab" class="nav nav-tabs" role="tablist">
<li class=""><a href="#view" role="tab" data-toggle="tab">View</a></li>
<li class="active"><a href="#edit" role="tab" data-toggle="tab">Edit</a></li>
<li class=""><a href="#delete" role="tab" data-toggle="tab">Delete</a></li>
</ul>
{/if}
<div id="myTabContent" class="tab-content">
<div class="tab-pane" id="view">
{if isset="$node"}
<hr>
<div class="container-fluid">
<div class="row" itemscope itemtype="http://schema.org/Article">
<div class="row">
<div class="col-sm-6 col-md-4 col-lg-3"><h1><span itemprop="name">{$node.title/}</span></h1></div>
</div>
<div class="row">
<div class="col-sm-6 col-md-4 col-lg-3"><span itemprop="text">{$node.content/}<span></div>
</div>
</div>
</div>
{/if}
</div>
<div class="tab-pane fade active in" id="edit">
{if isset="$user"}
<hr>
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
{if isset="$node"}
<form class="form-inline well" action="{$host/}/node/{$node.id/}" itemprop="url" method="POST">
<input type="hidden" name="method" value="PUT">
{/if}
{unless isset="$node"}
<form class="form-inline well" action="{$host/}/node" itemprop="url" method="POST">
{/unless/}
<fieldset>
<legend>Edit Node</legend>
<div class="span3">
<p>Add or Edit a Node</p>
</div>
<div class="row">
<div class="col-xs-1">
{if isset="$node"}
<label><span itemprop="name"><a href="{$host/}/node/{$node.id/}/title" rel="node">Title:</a></span></label>
{/if}
{unless isset="$node"}
<label><span itemprop="name">Title:</span> </label>
{/unless}
</div>
<div class="col-xs-7">
<input id="title" type="text" class="form-control" name="title" placeholder="Title" required value="{$node.title/}"/>
</div>
</div>
<div class="row">
<div class="col-xs-1">
{if isset="$node"}
<label> <span itemprop="description"><a href="{$host/}/node/{$node.id/}/content" rel="node">Summary:</a></span></label>
{/if}
{unless isset="$node"}
<label> <span itemprop="description">Summary:</span></label>
{/unless}
</div>
<div class="col-xs-7">
<textarea id="summary" rows="3" class="form-control" cols="100" name="summary" placeholder="Node summary" required>{$node.summary/}</textarea>
</div>
</div>
<div class="row">
<div class="col-xs-1">
{if isset="$node"}
<label> <span itemprop="text"><a href="{$host/}/node/{$node.id/}/content" rel="node">Content</a></span> </label>
{/if}
{unless isset="$node"}
<label> <span itemprop="text">Content:</span> </label>
{/unless}
</div>
<div class="col-xs-7">
<textarea id="content" rows="25" cols="100" class="form-control" name="content" placeholder="Node content" required>{$node.content/}</textarea>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
{/if}
</div>
</div>
<div class="tab-pane" id="delete">
{if isset="$user"}
<hr>
<div class="container-fluid">
{if isset="$node"}
<form action="{$host/}/node/{$node.id/}" method="POST" class="">
<input type="hidden" name="method" value="DELETE">
<fieldset>
<legend>Delete Node</legend>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Delete" />
</label>
</div>
</fieldset>
</form>
{/if}
</div>
{/if}
</div>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,70 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
<form class="form-inline well" action="{$host/}/node/{$id/}/content" method="POST" class="">
<input type="hidden" name="method" value="PUT">
<fieldset>
<legend>Edit Node Content</legend>
<div class="row">
<div class="col-xs-1">
<label> <span itemprop="text">Content:</span> </label>
</div>
<div class="col-xs-7">
<textarea id="content" rows="25" cols="100" class="form-control" name="content" placeholder="Node content" required>{$content/}</textarea>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Update" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,71 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
<form class="form-inline well" action="{$host/}/node/{$id/}/summary" method="POST">
<input type="hidden" name="method" value="PUT">
<fieldset>
<legend>Edit Node Summary</legend>
<div class="row">
<div class="col-xs-1">
<label> <span itemprop="text">Summary:</span> </label>
</div>
<div class="col-xs-7">
<textarea id="summary" rows="3" cols="80" name="summary" placeholder="Node summary" required>{$summary/}</textarea>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,70 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
<form class="form-inline well" action="{$host/}/node/{$id/}/title" method="POST">
<input type="hidden" name="method" value="PUT">
<fieldset>
<legend>Edit Node Title</legend>
<div class="row">
<div class="col-xs-1">
<label> <span itemprop="text">Title:</span> </label>
</div>
<div class="col-xs-7">
<input id="title" type="text" name="title" placeholder="Title" required value="{$title/}"/>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,19 +0,0 @@
note
description: "Summary description for {ESA_APPLICATION_CONSTANTS}."
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
APPLICATION_CONSTANTS
feature -- Access
major: INTEGER = 0
minor: INTEGER = 1
built: STRING = "0001"
version: STRING
do
Result := major.out + "." + minor.out + "." + built
end
end

View File

@@ -1,70 +0,0 @@
note
description: "API configuration factory"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
CONFIGURATION_FACTORY
inherit
SHARED_EXECUTION_ENVIRONMENT
SHARED_ERROR
feature -- Factory
roc_config (a_dir: detachable STRING): ROC_CONFIG
local
l_layout: APPLICATION_LAYOUT
l_email_service: ROC_EMAIL_SERVICE
l_database: DATABASE_CONNECTION
l_api_service: ROC_API_SERVICE
l_retried: BOOLEAN
do
if not l_retried then
if attached a_dir then
create l_layout.make_with_path (create {PATH}.make_from_string (a_dir))
else
create l_layout.make_default
end
log.write_information (generator + ".roc_config " + l_layout.path.name.out)
create l_email_service.make ((create {JSON_CONFIGURATION}).new_smtp_configuration(l_layout.application_config_path))
if attached (create {JSON_CONFIGURATION}).new_database_configuration (l_layout.application_config_path) as l_database_config then
create {DATABASE_CONNECTION_MYSQL} l_database.login_with_connection_string (l_database_config.connection_string)
create l_api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database))
create Result.make (l_database, l_api_service, l_email_service, l_layout)
if (create {ROC_JSON_CONFIGURATION}).is_web_mode(l_layout.application_config_path) then
Result.mark_web
elseif (create {ROC_JSON_CONFIGURATION}).is_html_mode(l_layout.application_config_path) then
Result.mark_html
end
set_successful
else
create {DATABASE_CONNECTION_NULL} l_database.make_common
create l_api_service.make (create {CMS_STORAGE_NULL})
create Result.make (l_database, l_api_service, l_email_service, l_layout)
set_last_error ("Database Connections", generator + ".roc_config")
log.write_error (generator + ".roc_config Error database connection" )
end
else
if attached a_dir then
create l_layout.make_with_path (create {PATH}.make_from_string (a_dir))
else
create l_layout.make_default
end
create l_email_service.make ((create {JSON_CONFIGURATION}).new_smtp_configuration(l_layout.application_config_path))
create {DATABASE_CONNECTION_NULL} l_database.make_common
create l_api_service.make (create {CMS_STORAGE_NULL})
create Result.make (l_database, l_api_service, l_email_service, l_layout)
end
rescue
set_last_error_from_exception ("Database Connection execution")
log.write_critical (generator + ".roc_config Database Connection execution exceptions")
l_retried := True
retry
end
end

View File

@@ -1,48 +0,0 @@
note
description: "Summary description for {ROC_JSON_CONFIGURATION}."
date: "$Date$"
revision: "$Revision$"
class
ROC_JSON_CONFIGURATION
inherit
JSON_CONFIGURATION
feature -- Access
is_html_mode (a_path: PATH): BOOLEAN
-- Is the server running on web mode?
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("server") as l_server and then
attached {JSON_STRING} l_server.item ("mode") as l_mode then
Result := l_mode.item.is_case_insensitive_equal_general ("html")
end
end
end
is_web_mode (a_path: PATH): BOOLEAN
-- Is the server running on web mode?
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("server") as l_server and then
attached {JSON_STRING} l_server.item ("mode") as l_mode then
Result := l_mode.item.is_case_insensitive_equal_general ("web")
end
end
end
end

View File

@@ -1,29 +0,0 @@
note
description: "Template shared common features to all the templates"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
deferred class
TEMPLATE_SHARED
inherit
ROC_TEMPLATE_PAGE
feature --
add_host (a_host: READABLE_STRING_GENERAL)
-- Add value `a_host' to `host'
do
template.add_value (a_host, "host")
end
add_user (a_user: detachable ANY)
-- Add value `a_host' to `host'
do
if attached a_user then
template.add_value (a_user,"user")
end
end
end

View File

@@ -1,143 +0,0 @@
note
description: "Summary description for {ROC_RESPONSE}."
date: "$Date$"
revision: "$Revision$"
class
ROC_RESPONSE
inherit
APP_HANDLER
TEMPLATE_SHARED
create
make
feature {NONE} -- Initialization
make (a_request: WSF_REQUEST; a_template: READABLE_STRING_32)
do
request := a_request
-- Set template to HTML
set_template_folder (html_path)
-- Build Common Template
set_template_file_name (a_template)
-- Process the current tempate.
set_value (a_request.absolute_script_url (""), "host")
if attached current_user_name (request) as l_user then
set_value (l_user, "user")
end
end
feature -- Access
request: WSF_REQUEST
feature -- Access
values: STRING_TABLE [detachable ANY]
do
Result := template.values
end
value (a_key: READABLE_STRING_GENERAL): detachable ANY
do
Result := template.values.item (a_key)
end
feature -- Element change
set_value (a_value: detachable ANY; a_key: READABLE_STRING_GENERAL)
do
template.add_value (a_value, a_key)
end
feature -- Output
send_to (res: WSF_RESPONSE)
do
process
if attached representation as l_output then
new_response (res, l_output, {HTTP_STATUS_CODE}.ok)
end
end
new_response_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
-- Redirect to `a_location'
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_current_date
h.put_location (a_location)
res.set_status_code ({HTTP_STATUS_CODE}.see_other)
res.put_header_text (h.string)
end
new_response_authenticate (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Handle forbidden.
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_current_date
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"CMS-User%"")
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.put_header_text (h.string)
end
new_response_denied (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Handle forbidden.
local
h: HTTP_HEADER
do
process
create h.make
if attached representation as l_output then
h.put_content_length (l_output.count)
end
h.put_content_type_text_html
h.put_current_date
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.put_header_text (h.string)
if attached representation as l_output then
res.put_string (l_output)
end
end
new_response_unauthorized (req: WSF_REQUEST; res: WSF_RESPONSE)
local
h: HTTP_HEADER
output: STRING
do
create h.make
h.put_content_type_text_html
h.put_current_date
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
res.put_header_text (h.string)
end
feature {NONE} -- Implemenation
new_response (res: WSF_RESPONSE; output: STRING; status_code: INTEGER)
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_content_length (output.count)
h.put_current_date
res.set_status_code (status_code)
res.put_header_text (h.string)
res.put_string (output)
end
end

View File

@@ -1,76 +0,0 @@
note
description: "Abstract template class"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
deferred class
ROC_TEMPLATE_PAGE
inherit
SHARED_TEMPLATE_CONTEXT
SHARED_LOGGER
ARGUMENTS
feature -- Status
representation: detachable STRING
-- String representation, if any.
set_template_folder (v: PATH)
-- Set template folder to `v'.
do
template_context.set_template_folder (v)
end
set_template_file_name (v: STRING)
-- Set `template' to `v'.
do
create template.make_from_file (v)
end
set_template (v: like template)
-- Set `template' to `v'.
do
template := v
end
template: TEMPLATE_FILE
layout: APPLICATION_LAYOUT
local
l_env: EXECUTION_ENVIRONMENT
once
create l_env
if attached separate_character_option_value ('d') as l_dir then
create Result.make_with_path (create {PATH}.make_from_string (l_dir))
else
create Result.make_default
end
end
html_path: PATH
-- Html template paths.
do
Result := layout.template_path.extended ("html")
end
feature -- Process
process
-- Process the current template.
do
template_context.enable_verbose
template.analyze
template.get_output
if attached template.output as l_output then
representation := l_output
debug
log.write_debug (generator + ".make " + l_output)
end
end
end
end

View File

@@ -1,119 +0,0 @@
note
description: "Abstract API service"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
deferred class
ROC_ABSTRACT_API
inherit
WSF_ROUTED_SKELETON_SERVICE
undefine
requires_proxy
redefine
execute_default
end
WSF_NO_PROXY_POLICY
WSF_URI_HELPER_FOR_ROUTED_SERVICE
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE
SHARED_CONNEG_HELPER
SHARED_LOGGER
feature {NONE} -- Initialization
make (a_esa_config: ROC_CONFIG; a_server: ROC_SERVER)
do
roc_config := a_esa_config
server := a_server
initialize_router
end
feature -- ESA
roc_config: ROC_CONFIG
-- Configuration
server: ROC_SERVER
-- Server
feature -- Router setup
setup_router
-- Setup `router'
deferred
end
layout: APPLICATION_LAYOUT
do
Result := roc_config.layout
end
feature -- Access
handle_debug (req: WSF_REQUEST; res: WSF_RESPONSE)
local
s: STRING_8
h: HTTP_HEADER
do
if req.is_get_request_method then
s := "debug"
create h.make_with_count (1)
h.put_content_type_text_html
h.put_content_length (s.count)
res.put_header_lines (h)
res.put_string (s)
else
create s.make (30_000)
across
req.form_parameters as c
loop
s.append (c.item.url_encoded_name)
s.append ("=")
s.append (c.item.string_representation)
s.append ("<br/>")
end
if s.is_empty then
req.read_input_data_into (s)
end
create h.make_with_count (1)
h.put_content_type_text_html
h.put_content_length (s.count)
res.put_header_lines (h)
res.put_string (s)
end
end
feature -- Handler
not_yet_implemented_uri_template_handler (msg: READABLE_STRING_8): WSF_URI_TEMPLATE_HANDLER
do
create {WSF_URI_TEMPLATE_AGENT_HANDLER} Result.make (agent not_yet_implemented(?, ?, msg))
end
not_yet_implemented (req: WSF_REQUEST; res: WSF_RESPONSE; msg: detachable READABLE_STRING_8)
local
m: WSF_NOT_IMPLEMENTED_RESPONSE
do
create m.make (req)
if msg /= Void then
m.set_body (msg)
end
res.send (m)
end
feature -- Default Execution
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Dispatch requests without a matching handler.
local
do
end
end

View File

@@ -1,87 +0,0 @@
note
description: "Eiffel Suppor API configuration"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
ROC_CONFIG
inherit
SHARED_ERROR
create
make
feature -- Initialization
make (a_database: DATABASE_CONNECTION; a_api_service: ROC_API_SERVICE; a_email_service: ROC_EMAIL_SERVICE; a_layout: APPLICATION_LAYOUT )
-- Create an object with defaults.
do
database := a_database
api_service := a_api_service
email_service := a_email_service
layout := a_layout
mark_api
ensure
database_set: database = a_database
api_service_set: api_service = a_api_service
email_service_set: email_service = a_email_service
layout_set: layout = a_layout
end
feature -- Access
is_successful: BOOLEAN
-- Is the configuration successful?
do
Result := successful
end
is_api: BOOLEAN
-- Is the server running on server mode API
is_web: BOOLEAN
-- Is the server running on server mode API
is_html: BOOLEAN
-- Is the server running on html mode API
database: DATABASE_CONNECTION
-- Database connection.
api_service: ROC_API_SERVICE
-- Support API.
email_service: ROC_EMAIL_SERVICE
-- Email service.
layout: APPLICATION_LAYOUT
-- Api layout.
mark_api
-- Set server mode to api.
do
is_api := True
is_html := False
is_web := False
end
mark_web
-- Set server mode to web.
do
is_web := True
is_api := False
is_html := False
end
mark_html
-- Set server mode to web.
do
is_html := True
is_api := False
is_web := False
end
end

View File

@@ -1,212 +0,0 @@
note
description: "[
application service
]"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
ROC_SERVER
inherit
WSF_LAUNCHABLE_SERVICE
rename
make_and_launch as make_and_launch_service
redefine
initialize
end
WSF_FILTERED_SERVICE
WSF_FILTER
rename
execute as execute_filter
end
SHARED_EXECUTION_ENVIRONMENT
export
{NONE} all
end
APPLICATION_CONSTANTS
REFACTORING_HELPER
ARGUMENTS
create
make_and_launch
feature {NONE} -- Initialization
make_and_launch
do
setup_config
create launcher
make_and_launch_service
end
initialize
-- Initialize current service.
do
Precursor
service_options := create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("roc.ini")
initialize_filter
end
feature {NONE} -- Launch operation
launcher: APPLICATION_LAUNCHER
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
l_retry: BOOLEAN
l_message: STRING
do
if not l_retry then
launcher.launch (a_service, opts)
else
-- error hanling.
create l_message.make (1024)
if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then
if attached l_exception.description as l_description then
l_message.append (l_description.as_string_32)
l_message.append ("%N%N")
elseif attached l_exception.trace as l_trace then
l_message.append (l_trace)
l_message.append ("%N%N")
else
l_message.append (l_exception.out)
l_message.append ("%N%N")
end
else
l_message.append ("The application crash without available information")
l_message.append ("%N%N")
end
roc_config.email_service.send_shutdown_email (l_message)
roc_config.log.write_emergency (generator + ".launch %N" + l_message)
end
rescue
l_retry := True
retry
end
feature {ROC_ABSTRACT_API} -- Services
api_service: ROC_REST_API
-- rest api.
local
s: like internal_api_service
do
s := internal_api_service
if s = Void then
create s.make (roc_config, Current)
internal_api_service := s
end
Result := s
end
feature {NONE} -- Internal
internal_api_service: detachable like api_service
feature -- ESA Configuraion
roc_config: ROC_CONFIG
-- Configuration.
setup_config
-- Configure API.
local
l_configuration_factory: CONFIGURATION_FACTORY
do
create l_configuration_factory
roc_config := l_configuration_factory.roc_config (separate_character_option_value ('d'))
if attached l_configuration_factory.last_error as l_error then
roc_config.set_last_error_from_handler (l_error)
else
roc_config.set_successful
end
end
feature -- Execute Filter
execute_filter (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
do
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
res.put_header_line ("ROCServer: " + version)
api_service.execute (req, res)
end
feature -- Filters
create_filter
-- Create `filter'.
local
f, l_filter: detachable WSF_FILTER
fh: WSF_CUSTOM_HEADER_FILTER
do
l_filter := Void
-- Header
create fh.make (1)
fh.set_next (l_filter)
fh.custom_header.put_header ("X-ROCServer: " + version)
l_filter := fh
-- Maintenance
create {WSF_MAINTENANCE_FILTER} f
f.set_next (l_filter)
l_filter := f
if launcher.is_console_output_supported then
-- Logging for nino
create {WSF_LOGGING_FILTER} f.make_with_output (io.output)
f.set_next (l_filter)
l_filter := f
end
-- CORS Authentication
create {CORS_FILTER} f
f.set_next (l_filter)
l_filter := f
-- Authentication
create {AUTHENTICATION_FILTER} f.make (roc_config)
f.set_next (l_filter)
l_filter := f
-- Logger Filter
create {LOGGER_FILTER} f.make (roc_config)
f.set_next (l_filter)
l_filter := f
-- Error Filter
create {ERROR_FILTER} f.make (roc_config)
f.set_next (l_filter)
l_filter := f
filter := l_filter
end
setup_filter
-- Setup `filter'.
local
f: WSF_FILTER
do
from
f := filter
until
not attached f.next as l_next
loop
f := l_next
end
f.set_next (Current)
end
end

View File

@@ -1,60 +0,0 @@
note
description: "Authentication filter."
author: "Olivier Ligot"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
AUTHENTICATION_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter
local
l_auth: HTTP_AUTHORIZATION
do
log.write_debug (generator + ".execute " )
create l_auth.make (req.http_authorization)
if attached req.raw_header_data as l_raw_data then
log.write_debug (generator + ".execute " + l_raw_data )
end
-- A valid user
if (attached l_auth.type as l_auth_type and then l_auth_type.is_case_insensitive_equal ("basic")) and then
attached l_auth.login as l_auth_login and then attached l_auth.password as l_auth_password then
if api_service.login_valid (l_auth_login, l_auth_password) then
if attached api_service.user_by_name (l_auth_login) as l_user then
req.set_execution_variable ("user", l_user)
execute_next (req, res)
else
-- Internal server error
end
else
log.write_error (generator + ".execute login_valid failed for: " + l_auth_login )
execute_next (req, res)
end
else
log.write_error (generator + ".execute Not valid")
execute_next (req, res)
end
end
note
copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,27 +0,0 @@
note
description: "CORS filter"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
CORS_FILTER
inherit
WSF_FILTER
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
local
l_header: HTTP_HEADER
do
create l_header.make
-- l_header.add_header_key_value ("Access-Control-Allow-Origin", "localhost")
l_header.add_header_key_value ("Access-Control-Allow-Headers", "*")
l_header.add_header_key_value ("Access-Control-Allow-Methods", "*")
l_header.add_header_key_value ("Access-Control-Allow-Credentials", "true")
res.put_header_lines (l_header)
execute_next (req, res)
end
end

View File

@@ -1,42 +0,0 @@
note
description: "Error filter"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
ERROR_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter
do
if roc_config.is_successful and then roc_config.api_service.successful then
log.write_information (generator + ".execute")
execute_next (req, res)
else
-- send internal server error.
end
end
note
copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,54 +0,0 @@
note
description: "Logger filter"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
LOGGER_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
local
s: STRING_8
do
log.write_debug (generator + ".execute")
create s.make (2048)
if attached req.content_type as l_type then
s.append ("[length=")
s.append_natural_64 (req.content_length_value)
s.append_character (']')
s.append_character (' ')
s.append (l_type.debug_output)
s.append_character ('%N')
end
append_iterable_to ("Path parameters", req.path_parameters, s)
append_iterable_to ("Query parameters", req.query_parameters, s)
append_iterable_to ("Form parameters", req.form_parameters, s)
if not s.is_empty then
log.write_debug (generator + ".execute" + s)
end
execute_next (req, res)
end
note
copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,48 +0,0 @@
note
description: "Abstrat Eiffel Support API Handler."
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
deferred class
APP_ABSTRACT_HANDLER
inherit
WSF_HANDLER
APP_HANDLER
SHARED_CONNEG_HELPER
feature -- Change
set_esa_config (a_esa_config: like roc_config)
-- Set `roc_config' to `a_esa_condig'.
do
roc_config := a_esa_config
ensure
esa_config_set: roc_config = a_esa_config
end
feature -- Access
roc_config: ROC_CONFIG
-- Configuration.
api_service: ROC_API_SERVICE
-- api Service.
do
Result := roc_config.api_service
end
email_service: ROC_EMAIL_SERVICE
-- Email Service.
do
Result := roc_config.email_service
end
is_web: BOOLEAN
do
Result := roc_config.is_web
end
end

View File

@@ -1,98 +0,0 @@
note
description: "Summary description for {ESA_HANDLER}."
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
APP_HANDLER
inherit
SHARED_LOGGER
feature -- User
current_user_name (req: WSF_REQUEST): detachable READABLE_STRING_32
-- Current user name or Void in case of Guest users.
note
EIS: "src=eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
do
if attached {CMS_USER} current_user (req) as l_user then
Result := l_user.name
end
end
current_user (req: WSF_REQUEST): detachable CMS_USER
-- Current user or Void in case of Guest user.
note
EIS: "eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
do
if attached {CMS_USER} req.execution_variable ("user") as l_user then
Result := l_user
end
end
feature -- Media Type
current_media_type (req: WSF_REQUEST): detachable READABLE_STRING_32
-- Current media type or Void if it's not acceptable.
do
if attached {STRING} req.execution_variable ("media_type") as l_type then
Result := l_type
end
end
feature -- Absolute Host
absolute_host (req: WSF_REQUEST; a_path:STRING): STRING
do
Result := req.absolute_script_url (a_path)
if Result.last_index_of ('/', Result.count) = Result.count then
Result.remove_tail (1)
end
log.write_debug (generator + ".absolute_host " + Result )
end
feature -- Compression
current_compression (req: WSF_REQUEST): detachable READABLE_STRING_32
-- Current compression encoding or Void if it's not acceptable.
do
if attached {STRING} req.execution_variable ("compression") as l_encoding then
Result := l_encoding
end
end
feature {NONE} -- Implementations
append_iterable_to (a_title: READABLE_STRING_8; it: detachable ITERABLE [WSF_VALUE]; s: STRING_8)
local
n: INTEGER
do
if it /= Void then
across it as c loop
n := n + 1
end
if n > 0 then
s.append (a_title)
s.append_character (':')
s.append_character ('%N')
across
it as c
loop
s.append (" - ")
s.append (c.item.url_encoded_name)
s.append_character (' ')
s.append_character ('{')
s.append (c.item.generating_type)
s.append_character ('}')
s.append_character ('=')
s.append (c.item.debug_output.as_string_8)
s.append_character ('%N')
end
end
end
end
end

View File

@@ -1,57 +0,0 @@
note
description: "Summary description for {NAVIGATION_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
NAVIGATION_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "modules/navigation.tpl")
l_page.send_to (res)
end
end

View File

@@ -1,190 +0,0 @@
note
description: "Summary description for {NEW_CONTENT_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
NODE_CONTENT_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
if attached current_user_name (req) then
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create l_page.make (req, "modules/node_content.tpl")
l_page.set_value (l_node.content, "content")
l_page.set_value (l_id.value, "id")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
else
do_error (req, res, l_id)
end
else
-- Todo extract method
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
if attached current_user_name (req) then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
end
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
to_implement ("Check if user has permissions")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.integer_value)
api_service.update_node_content (l_user.id, u_node.id, u_node.content)
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "master2/error.tpl")
if a_id.is_integer then
-- resource not found
l_page.set_value ("404", "code")
else
-- bad request
l_page.set_value ("400", "code")
end
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to(res)
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING}req.form_parameter ("content") as l_content then
Result.set_content (l_content.value)
end
end
end

View File

@@ -1,225 +0,0 @@
note
description: "Summary description for {NODE_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
NODE_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put,
do_delete
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create l_page.make (req, "modules/node.tpl")
l_page.set_value (l_node, "node")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
else
do_error (req, res, l_id)
end
else
-- Factory
new_node (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
to_implement ("Check user permissions!!!")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("DELETE") then
do_delete (req, res)
elseif l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
end
else
do_error (req, res, l_id)
end
else
-- New node
u_node := extract_data_form (req)
u_node.set_author (l_user)
api_service.new_node (u_node)
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
do
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.integer_value)
api_service.update_node (l_user.id,u_node)
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
-- Internal server error
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user_name (req) then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
api_service.delete_node (l_id.integer_value)
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
-- Internal server error
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "master2/error.tpl")
if a_id.is_integer then
-- resource not found
l_page.set_value ("404", "code")
else
-- bad request
l_page.set_value ("400", "code")
end
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
feature {NONE} -- Node
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: ROC_RESPONSE
do
if attached current_user_name (req) then
create l_page.make (req, "modules/node.tpl")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
else
(create {ROC_RESPONSE}.make (req, "")).new_response_unauthorized (req, res)
end
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
Result.set_title (l_title.value)
end
if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then
Result.set_summary (l_summary.value)
end
if attached {WSF_STRING} req.form_parameter ("content") as l_content then
Result.set_content (l_content.value)
end
end
end

View File

@@ -1,199 +0,0 @@
note
description: "Summary description for {NODE_SUMMARY_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
NODE_SUMMARY_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
if attached current_user_name (req) then
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create l_page.make (req, "modules/node_summary.tpl")
l_page.set_value (l_node.summary, "summary")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.set_value (l_id.value, "id")
l_page.send_to (res)
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
if attached current_user_name (req) then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
end
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
to_implement ("Check if user has permissions!!!")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.integer_value)
api_service.update_node_summary (l_user.id,u_node.id, u_node.summary)
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "master2/error.tpl")
if a_id.is_integer then
-- resource not found
l_page.set_value ("404", "code")
else
-- bad request
l_page.set_value ("400", "code")
end
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to(res)
end
feature {NONE} -- Node
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "modules/node.tpl")
l_page.send_to (res)
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING}req.form_parameter ("summary") as l_summary then
Result.set_summary (l_summary.value)
end
end
end

View File

@@ -1,199 +0,0 @@
note
description: "Summary description for {NODE_TITLE_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
NODE_TITLE_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
if attached current_user_name (req) as l_user then
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create l_page.make (req, "modules/node_title.tpl")
l_page.set_value (l_node.title, "title")
l_page.set_value (l_id.value, "id")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
if attached current_user_name (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
end
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
to_implement ("Check if user has permissions")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.integer_value)
api_service.update_node_title (l_user.id,u_node.id, u_node.title)
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
create l_page.make (req, "master2/error.tpl")
l_page.set_value ("500", "code")
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
else
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "master2/error.tpl")
if a_id.is_integer then
-- resource not found
l_page.set_value ("404", "code")
else
-- bad request
l_page.set_value ("400", "code")
end
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
feature {NONE} -- Node
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "modules/node.tpl")
l_page.send_to (res)
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
Result.set_title (l_title.value)
end
end
end

View File

@@ -1,62 +0,0 @@
note
description: "Summary description for {NODES_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
NODES_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "modules/nodes.tpl")
l_page.set_value (api_service.nodes, "nodes")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
end
end

View File

@@ -1,63 +0,0 @@
note
description: "Handle Login using Basic Authentication"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
ROC_LOGIN_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_FILTER
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached {STRING_32} current_user_name (req) as l_user then
(create {ROC_RESPONSE}.make(req,"")).new_response_redirect (req, res, req.absolute_script_url(""))
else
(create {ROC_RESPONSE}.make(req,"")).new_response_authenticate (req, res)
end
end
end

View File

@@ -1,60 +0,0 @@
note
description: "Handle Logoff for Basic Authentication"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
ROC_LOGOFF_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
log.write_information(generator + ".do_get Processing logoff")
if attached req.query_parameter ("prompt") as l_prompt then
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
else
req.unset_execution_variable ("user")
(create {ROC_RESPONSE}.make(req,"master2/logoff.tpl")).new_response_denied (req, res)
end
end
end

View File

@@ -1,63 +0,0 @@
note
description: "ROOT_HANDLER."
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
ROC_ROOT_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "layout2.tpl")
l_page.set_value (api_service.recent_nodes (0,5), "nodes")
l_page.set_value (is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
end
end

View File

@@ -1,163 +0,0 @@
note
description: "Summary description for {USER_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
USER_HANDLER
inherit
APP_ABSTRACT_HANDLER
rename
set_esa_config as make
end
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put,
do_delete
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: ROC_RESPONSE
do
-- Existing node
create l_page.make (req, "modules/register.tpl")
l_page.set_value (roc_config.is_web, "web")
l_page.set_value (roc_config.is_html, "html")
l_page.send_to (res)
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
l_page: ROC_RESPONSE
do
-- New user
api_service.new_user (extract_data_form (req))
if api_service.successful then
(create {ROC_RESPONSE}.make (req, "")).new_response_redirect (req, res, req.absolute_script_url (""))
else
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
do
end
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: ROC_RESPONSE
do
create l_page.make (req, "master2/error.tpl")
if a_id.is_integer then
-- resource not found
l_page.set_value ("404", "code")
else
-- bad request
l_page.set_value ("400", "code")
end
l_page.set_value (req.absolute_script_url (req.path_info), "request")
l_page.send_to (res)
end
feature {NONE} -- Node
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: ROC_RESPONSE
do
if attached current_user_name (req) then
create l_page.make (req, "modules/node.tpl")
l_page.send_to (res)
else
(create {ROC_RESPONSE}.make (req, "")).new_response_unauthorized (req, res)
end
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_USER
-- Extract request form data and build a object
-- user
do
create Result.make ("")
if attached {WSF_STRING} req.form_parameter ("username") as l_username then
Result.set_name (l_username)
end
if
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
attached {WSF_STRING} req.form_parameter ("check_password") as l_check_password and then
l_password.value.is_case_insensitive_equal (l_check_password.value)
then
Result.set_password (l_password)
end
if attached {WSF_STRING} req.form_parameter ("email") as l_email then
Result.set_email (l_email)
end
end
end

View File

@@ -1,126 +0,0 @@
note
description: "API Service facade to the underlying business logic"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
ROC_API_SERVICE
inherit
SHARED_ERROR
REFACTORING_HELPER
create make
feature -- Initialize
make (a_storage: CMS_STORAGE)
-- Create the API service with an storege `a_storage'.
do
storage := a_storage
set_successful
ensure
storage_set: storage = a_storage
end
feature -- Access
login_valid (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
local
l_security: SECURITY_PROVIDER
do
Result := storage.is_valid_credential (l_auth_login, l_auth_password)
end
feature -- Access: Node
nodes: LIST[CMS_NODE]
-- List of nodes.
do
fixme ("Implementation")
Result := storage.recent_nodes (0, 10)
end
recent_nodes (a_offset, a_rows: INTEGER): LIST[CMS_NODE]
-- List of the `a_rows' most recent nodes starting from `a_offset'.
do
Result := storage.recent_nodes (a_offset, a_rows)
end
node (a_id: INTEGER_64): detachable CMS_NODE
-- Node by ID.
do
fixme ("Check preconditions")
Result := storage.node (a_id)
end
feature -- Change: Node
new_node (a_node: CMS_NODE)
-- Add a new node
do
storage.save_node (a_node)
end
delete_node (a_id: INTEGER_64)
do
storage.delete_node (a_id)
end
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
do
storage.update_node (a_id,a_node)
end
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
do
fixme ("Check preconditions")
storage.update_node_title (a_id,a_node_id,a_title)
end
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
do
fixme ("Check preconditions")
storage.update_node_summary (a_id,a_node_id, a_summary)
end
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
do
fixme ("Check preconditions")
storage.update_node_content (a_id,a_node_id, a_content)
end
feature -- Access: User
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
do
Result := storage.user_by_name (a_username)
end
feature -- Change User
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
do
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
storage.save_user (a_user)
else
fixme ("Add error")
end
end
feature {NONE} -- Implemenataion
storage: CMS_STORAGE
-- Persistence storage
end

View File

@@ -1,127 +0,0 @@
note
description: "Provides email access"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
ROC_EMAIL_SERVICE
inherit
SHARED_ERROR
create
make
feature {NONE} -- Initialization
make (a_smtp_server: READABLE_STRING_32)
-- Create an instance of {ESA_EMAIL_SERVICE} with an smtp_server `a_smtp_server'.
-- Using "noreplies@eiffel.com" as admin email.
local
l_address_factory: INET_ADDRESS_FACTORY
do
-- Get local host name needed in creation of SMTP_PROTOCOL.
create l_address_factory
create smtp_protocol.make (a_smtp_server, l_address_factory.create_localhost.host_name)
set_successful
end
admin_email: IMMUTABLE_STRING_8
-- Administrator email.
once
Result := "noreplies@eiffel.com"
end
webmaster_email: IMMUTABLE_STRING_8
-- Webmaster email.
once
Result := "webmaster@eiffel.com"
end
smtp_protocol: SMTP_PROTOCOL
-- SMTP protocol.
feature -- Basic Operations
send_template_email (a_to, a_token, a_host: STRING)
-- Send successful registration message containing activation code `a_token' to `a_to'.
require
attached_to: a_to /= Void
attached_token: a_token /= Void
attached_host: a_host /= Void
local
l_content: STRING
l_url: URL_ENCODER
l_path: PATH
l_html: HTML_ENCODER
l_email: EMAIL
do
if successful then
log.write_information (generator + ".send_post_registration_email to [" + a_to + "]" )
create l_path.make_current
create l_url
create l_html
create l_content.make (1024)
l_content.append ("Thank you for registering at CMS.%N%NTo complete your registration, please click on this link to activate your account:%N%N")
l_content.append (a_host)
l_content.append ("/activation?code=")
l_content.append (l_url.encoded_string (a_token))
l_content.append ("&email=")
l_content.append (l_url.encoded_string (a_to))
l_content.append ("%N%NOnce there, please enter the following information and then click the Activate Account, button.%N%N")
l_content.append ("Your e-mail: ")
l_content.append (l_html.encoded_string (a_to))
l_content.append ("%N%NYour activation code: ")
l_content.append (l_html.encoded_string(a_token))
l_content.append ("%N%NThank you for joining us.%N%N CMS team.")
l_content.append (Disclaimer)
-- Create our message.
create l_email.make_with_entry (admin_email, a_to)
l_email.set_message (l_content)
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, "CMS Site: Account Activation")
send_email (l_email)
end
end
send_shutdown_email (a_message: READABLE_STRING_GENERAL)
-- Send email shutdown cause by an unexpected condition.
local
l_email: EMAIL
l_content: STRING
do
create l_email.make_with_entry (admin_email, webmaster_email)
create l_content.make (2048)
l_content.append (a_message.as_string_32)
l_email.set_message (l_content)
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, "ROC API exception")
send_email (l_email)
end
feature {NONE} -- Implementation
send_email (a_email: EMAIL)
-- Send the email represented by `a_email'.
local
l_retried: BOOLEAN
do
if not l_retried then
log.write_information (generator + ".send_email Process send email.")
smtp_protocol.initiate_protocol
smtp_protocol.transfer (a_email)
smtp_protocol.close_protocol
log.write_information (generator + ".send_email Email sent.")
set_successful
else
log.write_error (generator + ".send_email Email not send" + last_error_message )
end
rescue
set_last_error_from_exception (generator + ".send_email")
l_retried := True
retry
end
Disclaimer: STRING = "This email is generated automatically, and the address is not monitored for responses. If you try contacting us by using %"reply%", you will not receive an answer."
-- Email not monitored disclaimer.
end

View File

@@ -1,185 +0,0 @@
note
description: "[
REST API configuration
We manage URI and Uri templates using Routers. They are used to delegate calls (to the corresponing handlers) based on a URI template.
We define a Rooter and attach handlers to it.
]"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
ROC_REST_API
inherit
ROC_ABSTRACT_API
create
make
feature -- Initialization
setup_router
-- Setup `router'.
local
fhdl: WSF_FILE_SYSTEM_HANDLER
do
configure_api_root
configure_api_node
configure_api_navigation
configure_api_login
configure_api_nodes
configure_api_node_title
configure_api_node_summary
configure_api_node_content
configure_api_logoff
configure_api_register
create fhdl.make_hidden_with_path (layout.www_path)
fhdl.disable_index
fhdl.set_not_found_handler (agent (ia_uri: READABLE_STRING_8; ia_req: WSF_REQUEST; ia_res: WSF_RESPONSE)
do
execute_default (ia_req, ia_res)
end)
router.handle_with_request_methods ("/", fhdl, router.methods_GET)
end
feature -- Configure Resources Routes
configure_api_root
local
l_root_handler:ROC_ROOT_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_root_handler.make (roc_config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/", l_root_handler, l_methods)
end
configure_api_node
local
l_report_handler: NODE_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
router.handle_with_request_methods ("/node", l_report_handler, l_methods)
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
l_methods.enable_delete
router.handle_with_request_methods ("/node/{id}", l_report_handler, l_methods)
end
configure_api_navigation
local
l_report_handler: NAVIGATION_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/navigation", l_report_handler, l_methods)
end
configure_api_login
local
l_report_handler: ROC_LOGIN_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/login", l_report_handler, l_methods)
end
configure_api_logoff
local
l_report_handler: ROC_LOGOFF_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/logoff", l_report_handler, l_methods)
end
configure_api_nodes
local
l_report_handler: NODES_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/nodes", l_report_handler, l_methods)
end
configure_api_node_summary
local
l_report_handler: NODE_SUMMARY_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
router.handle_with_request_methods ("/node/{id}/summary", l_report_handler, l_methods)
end
configure_api_node_title
local
l_report_handler: NODE_TITLE_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
router.handle_with_request_methods ("/node/{id}/title", l_report_handler, l_methods)
end
configure_api_node_content
local
l_report_handler: NODE_CONTENT_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods)
end
configure_api_register
local
l_report_handler: USER_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (roc_config)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
router.handle_with_request_methods ("/user", l_report_handler, l_methods)
end
end

View File

@@ -1,48 +0,0 @@
note
description: "Conneg Helper"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
SHARED_CONNEG_HELPER
feature -- Access
conneg (req: WSF_REQUEST): SERVER_CONTENT_NEGOTIATION
-- Content negotiatior for all requests.
once
create Result.make ({HTTP_MIME_TYPES}.text_html, "en", "UTF-8", "identity")
end
mime_types_supported (req: WSF_REQUEST): LIST [STRING]
-- All values for Accept header that `Current' can serve.
do
create {ARRAYED_LIST [STRING]} Result.make_from_array (<<{HTTP_MIME_TYPES}.text_html, "application/vnd.collection+json">>)
Result.compare_objects
ensure
mime_types_supported_includes_default: Result.has (conneg (req).default_media_type)
end
media_type_variants (req: WSF_REQUEST): HTTP_ACCEPT_MEDIA_TYPE_VARIANTS
-- Media type negotiation.
do
Result := conneg (req).media_type_preference (mime_types_supported (req), req.http_accept)
end
compression_supported (req: WSF_REQUEST): LIST [STRING]
-- All values for Accept-Encofing header that `Current' can serve.
do
create {ARRAYED_LIST [STRING]} Result.make_from_array (<<"identity","deflate">>)
Result.compare_objects
ensure
compression_supported_includes_default: Result.has (conneg (req).default_encoding)
end
compression_variants (req: WSF_REQUEST): HTTP_ACCEPT_ENCODING_VARIANTS
-- Compression negotiation.
do
Result := conneg (req).encoding_preference (compression_supported (req), req.http_accept_encoding)
end
end

View File

@@ -1,58 +0,0 @@
note
description: "Provide input validation"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
deferred class
ROC_INPUT_VALIDATOR
feature -- Basic Operations
input_from (a_request: ITERABLE [WSF_VALUE])
-- Update current object using parameters extracted from QUERY_STRING.
-- If there are errors they are set to the errors parameter.
do
if attached {STRING_TABLE[WSF_VALUE]} a_request as l_table_request then
validate (l_table_request)
end
end
feature -- Validation
validate (a_request: STRING_TABLE [WSF_VALUE])
-- Validate input for control `a_request'.
deferred
end
feature -- Access
acceptable_query_parameters: ARRAY[STRING]
-- The parameters are optionals, more parameters is a bad request, the order is not important.
deferred
end
feature -- Errors
errors: STRING_TABLE[READABLE_STRING_32]
-- Hash table with errors and descriptions.
has_error: BOOLEAN
-- Has errors the last request?
do
Result := not errors.is_empty
end
error_message: STRING
-- String representation.
do
create Result.make_empty
across errors as c loop
Result.append (c.item)
Result.append ("%N")
end
end
end -- class EFA_INPUT_VALIDATOR

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="roc_api" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="roc_api">
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
<target name="common" abstract="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
@@ -10,13 +10,15 @@
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms\cms-safe.ecf" readonly="false"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\layout\layout-safe.ecf" readonly="false"/>
<library name="persistence_mysql" location="..\..\library\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target>
<target name="roc_api_any" extends="common">
<target name="demo_any" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>
@@ -24,24 +26,24 @@
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="roc_api_nino" extends="common">
<target name="demo_nino" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="roc_api_cgi" extends="common">
<target name="demo_cgi" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\cgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="roc_api_libfcgi" extends="common">
<target name="demo_libfcgi" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="roc_api" extends="roc_api_nino">
<target name="demo" extends="demo_nino">
</target>
</system>

View File

@@ -11,8 +11,8 @@
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="cms" location="..\..\..\..\cms\cms-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\..\..\model\model-safe.ecf" readonly="false"/>
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>

View File

@@ -0,0 +1,11 @@
[layout]
root-dir=site/www
themes-dir=site/themes
[site]
name=Eiffel CMS
email=your@email.com
theme=bootstrap
[misc]
smtp=localhost

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More