From 36dc48125c5ad4988d117dfda45c664bfad27464 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 8 Oct 2014 16:33:41 -0300 Subject: [PATCH 01/20] Clean code: removed unused variables. Move BASIC_AUTH module to ROC_SERVER setup, as an example of module extension --- cms/src/configuration/cms_default_setup.e | 4 ---- cms/src/modules/basic_auth/handler/basic_auth_login_handler.e | 2 -- cms/src/modules/node/handler/node_content_handler.e | 3 --- cms/src/modules/node/handler/node_handler.e | 1 - cms/src/modules/node/handler/node_summary_handler.e | 2 -- cms/src/modules/node/handler/node_title_handler.e | 2 -- cms/src/service/cms_api_service.e | 2 -- cms/src/service/response/cms_generic_response.e | 1 - examples/roc_api/src/ewf_roc_server.e | 3 +-- 9 files changed, 1 insertion(+), 19 deletions(-) diff --git a/cms/src/configuration/cms_default_setup.e b/cms/src/configuration/cms_default_setup.e index e1bf624..8918a36 100644 --- a/cms/src/configuration/cms_default_setup.e +++ b/cms/src/configuration/cms_default_setup.e @@ -62,10 +62,6 @@ feature {NONE} -- Initialization -- modules.extend (m) - create {BASIC_AUTH_MODULE} m.make (Current) - m.enable - modules.extend (m) - create {NODE_MODULE} m.make (Current) m.enable modules.extend (m) diff --git a/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e b/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e index a0e6df8..4035e0f 100644 --- a/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e +++ b/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e @@ -47,8 +47,6 @@ feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - l_page: CMS_RESPONSE do log.write_information(generator + ".do_get Processing basic auth login") if attached {STRING_32} current_user_name (req) as l_user then diff --git a/cms/src/modules/node/handler/node_content_handler.e b/cms/src/modules/node/handler/node_content_handler.e index a7113b7..31b911a 100644 --- a/cms/src/modules/node/handler/node_content_handler.e +++ b/cms/src/modules/node/handler/node_content_handler.e @@ -88,8 +88,6 @@ feature -- HTTP Methods do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - l_page: CMS_RESPONSE do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then @@ -116,7 +114,6 @@ feature -- HTTP Methods -- local u_node: CMS_NODE - l_page: CMS_RESPONSE do to_implement ("Check if user has permissions") if attached current_user (req) as l_user then diff --git a/cms/src/modules/node/handler/node_handler.e b/cms/src/modules/node/handler/node_handler.e index e9d789f..e4257b6 100644 --- a/cms/src/modules/node/handler/node_handler.e +++ b/cms/src/modules/node/handler/node_handler.e @@ -85,7 +85,6 @@ feature -- HTTP Methods -- local u_node: CMS_NODE - l_page: CMS_RESPONSE do to_implement ("Check user permissions!!!") if attached current_user (req) as l_user then diff --git a/cms/src/modules/node/handler/node_summary_handler.e b/cms/src/modules/node/handler/node_summary_handler.e index d3ec258..96f3c36 100644 --- a/cms/src/modules/node/handler/node_summary_handler.e +++ b/cms/src/modules/node/handler/node_summary_handler.e @@ -87,8 +87,6 @@ feature -- HTTP Methods do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - u_node: CMS_NODE do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then diff --git a/cms/src/modules/node/handler/node_title_handler.e b/cms/src/modules/node/handler/node_title_handler.e index 570b155..a5dfe9d 100644 --- a/cms/src/modules/node/handler/node_title_handler.e +++ b/cms/src/modules/node/handler/node_title_handler.e @@ -86,8 +86,6 @@ feature -- HTTP Methods do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - u_node: CMS_NODE do if attached current_user_name (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then diff --git a/cms/src/service/cms_api_service.e b/cms/src/service/cms_api_service.e index c7b69ff..a7d4c8f 100644 --- a/cms/src/service/cms_api_service.e +++ b/cms/src/service/cms_api_service.e @@ -29,8 +29,6 @@ feature -- Initialize feature -- Access is_valid_credential (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 diff --git a/cms/src/service/response/cms_generic_response.e b/cms/src/service/response/cms_generic_response.e index 380a391..371bc05 100644 --- a/cms/src/service/response/cms_generic_response.e +++ b/cms/src/service/response/cms_generic_response.e @@ -50,7 +50,6 @@ feature -- Responses -- Handle not authorized. local h: HTTP_HEADER - output: STRING do create h.make h.put_content_type_text_html diff --git a/examples/roc_api/src/ewf_roc_server.e b/examples/roc_api/src/ewf_roc_server.e index 1e02a20..875128d 100644 --- a/examples/roc_api/src/ewf_roc_server.e +++ b/examples/roc_api/src/ewf_roc_server.e @@ -117,7 +117,6 @@ feature -- CMS Initialization initialize_cms (a_setup: CMS_SETUP) local cms: CMS_SERVICE - l_modules: CMS_MODULE_COLLECTION do log.write_debug (generator + ".initialize_cms") @@ -134,7 +133,7 @@ feature -- CMS setup local m: CMS_MODULE do - create {NODE_MODULE} m.make (a_setup) + create {BASIC_AUTH_MODULE} m.make (a_setup) m.enable a_setup.modules.extend (m) end From 8d79447cf8aed6763e88294c7d08f4371d7c3d13 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Thu, 9 Oct 2014 10:01:49 -0300 Subject: [PATCH 02/20] Initial Import: Database transaction handling. Initial Import: Error handling using ewf error library. Added a CMS_ERROR_FILTER as part of registered filters of CMS_SERVICE --- cms/cms.ecf | 2 + cms/src/configuration/cms_default_setup.e | 40 ++++++- cms/src/configuration/cms_setup.e | 6 + cms/src/service/cms_service.e | 6 + cms/src/service/filter/cms_error_filter.e | 33 ++++++ .../common/database/database_connection.e | 61 +++++++++- .../common/database/database_handler.e | 55 +++++++-- .../common/database/database_handler_impl.e | 107 +++++------------- .../database/database_iteration_cursor.e | 2 +- .../database/database_no_change_error.e | 27 +++++ .../common/database/database_query.e | 27 +---- .../common/database/error/database_error.e | 23 ++++ .../{ => error}/database_error_handler.e | 16 +-- .../{ => error}/shared_error_handler.e | 14 ++- .../mysql/src/cms_storage_mysql.e | 6 + .../src/database/database_connection_mysql.e | 16 +-- .../mysql/src/provider/node_data_provider.e | 8 -- .../mysql/src/provider/role_data_provider.e | 10 +- .../mysql/src/provider/user_data_provider.e | 8 -- .../mysql/tests/util/clean_db.e | 2 + 20 files changed, 302 insertions(+), 167 deletions(-) create mode 100644 cms/src/service/filter/cms_error_filter.e create mode 100644 persistence/implementation/common/database/database_no_change_error.e create mode 100644 persistence/implementation/common/database/error/database_error.e rename persistence/implementation/common/database/{ => error}/database_error_handler.e (60%) rename persistence/implementation/common/database/{ => error}/shared_error_handler.e (78%) diff --git a/cms/cms.ecf b/cms/cms.ecf index dc20d24..0248847 100644 --- a/cms/cms.ecf +++ b/cms/cms.ecf @@ -10,6 +10,8 @@ + + diff --git a/cms/src/configuration/cms_default_setup.e b/cms/src/configuration/cms_default_setup.e index 8918a36..eabc20c 100644 --- a/cms/src/configuration/cms_default_setup.e +++ b/cms/src/configuration/cms_default_setup.e @@ -17,6 +17,7 @@ feature {NONE} -- Initialization make (a_layout: CMS_LAYOUT) do + create error_handler.make layout := a_layout create configuration.make (layout) initialize @@ -28,7 +29,6 @@ feature {NONE} -- Initialization create modules.make (3) build_api_service build_mailer - initialize_modules end @@ -61,7 +61,6 @@ feature {NONE} -- Initialization -- m.enable -- modules.extend (m) - create {NODE_MODULE} m.make (Current) m.enable modules.extend (m) @@ -89,15 +88,44 @@ feature -- Access build_api_service local l_database: DATABASE_CONNECTION + l_retry: BOOLEAN + l_message: STRING do - to_implement ("Refactor database setup") - if attached (create {JSON_CONFIGURATION}).new_database_configuration (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 api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database)) + if not l_retry then + to_implement ("Refactor database setup") + if attached (create {JSON_CONFIGURATION}).new_database_configuration (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 api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database)) + else + create {DATABASE_CONNECTION_NULL} l_database.make_common + create api_service.make (create {CMS_STORAGE_NULL}) + 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 api_service.make (create {CMS_STORAGE_NULL}) + 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 + l_retry := True + retry end build_auth_engine diff --git a/cms/src/configuration/cms_setup.e b/cms/src/configuration/cms_setup.e index f0af327..0e6189d 100644 --- a/cms/src/configuration/cms_setup.e +++ b/cms/src/configuration/cms_setup.e @@ -32,6 +32,12 @@ feature -- Access deferred end + +feature -- Status Report + + error_handler: ERROR_HANDLER + -- Error handler. + feature -- Access: Site site_id: READABLE_STRING_8 diff --git a/cms/src/service/cms_service.e b/cms/src/service/cms_service.e index 37a4759..84b67e6 100644 --- a/cms/src/service/cms_service.e +++ b/cms/src/service/cms_service.e @@ -165,9 +165,15 @@ feature -- Filters do log.write_debug (generator + ".create_filter") l_filter := Void + -- Maintenance create {WSF_MAINTENANCE_FILTER} f f.set_next (l_filter) + l_filter := f + + -- Error Filter + create {CMS_ERROR_FILTER} f.make (setup) + f.set_next (l_filter) l_filter := f -- Include filters from modules diff --git a/cms/src/service/filter/cms_error_filter.e b/cms/src/service/filter/cms_error_filter.e new file mode 100644 index 0000000..8a2f154 --- /dev/null +++ b/cms/src/service/filter/cms_error_filter.e @@ -0,0 +1,33 @@ +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 setup.error_handler.has_error then + log.write_information (generator + ".execute") + execute_next (req, res) + else + log.write_critical (generator + ".execute" + setup.error_handler.as_string_representation ) + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + setup.error_handler.reset + end + end + +end diff --git a/persistence/implementation/common/database/database_connection.e b/persistence/implementation/common/database/database_connection.e index 7591273..cfb9fd9 100644 --- a/persistence/implementation/common/database/database_connection.e +++ b/persistence/implementation/common/database/database_connection.e @@ -10,7 +10,7 @@ inherit DATABASE_CONFIG - SHARED_ERROR + SHARED_ERROR_HANDLER feature {NONE} -- Initialization @@ -72,6 +72,65 @@ feature -- Database Setup keep_connection: BOOLEAN -- Keep connection alive? +feature -- Transactions + + begin_transaction + -- Start a transaction which will be terminated by a call to `rollback' or `commit'. + local + rescued: BOOLEAN + do + if not rescued then + if db_control.is_ok then + db_control.begin + else + database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code) + end + end + rescue + rescued := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + db_control.reset + retry + end + + commit + -- Commit updates in the database. + local + rescued: BOOLEAN + do + if not rescued then + if db_control.is_ok then + db_control.commit + else + database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code) + end + end + rescue + rescued := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + db_control.reset + retry + end + + rollback + -- Rollback updates in the database. + local + rescued: BOOLEAN + do + if not rescued then + if db_control.is_ok then + db_control.rollback + else + database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code) + end + end + rescue + rescued := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + db_control.reset + retry + end + feature -- Change Element not_keep_connection diff --git a/persistence/implementation/common/database/database_handler.e b/persistence/implementation/common/database/database_handler.e index 3551e4a..875b7a7 100644 --- a/persistence/implementation/common/database/database_handler.e +++ b/persistence/implementation/common/database/database_handler.e @@ -8,7 +8,7 @@ deferred class inherit - SHARED_ERROR + SHARED_ERROR_HANDLER feature -- Access @@ -42,15 +42,15 @@ feature -- Modifiers feature -- Functionality Store Procedures - execute_reader - -- Execute store. + execute_store_reader + -- Execute a `store' to read data. require store_not_void: store /= void deferred end - execute_writer - -- Execute store. + execute_store_writer + -- Execute a `store' to write data. require store_not_void: store /= void deferred @@ -59,14 +59,14 @@ feature -- Functionality Store Procedures feature -- SQL Queries execute_query - -- Execute query. + -- Execute sql query, the read data from the database. require query_not_void: query /= void deferred end execute_change - -- Execute sqlquery that update/add data. + -- Execute sql query that update/add data. require query_not_void: query /= void deferred @@ -147,14 +147,49 @@ feature -- Access feature -- Status Report - has_error: BOOLEAN - -- Is there an error? - count: INTEGER -- Number of rows, last execution. deferred end + connection: DATABASE_CONNECTION + -- Database connection. + + db_control: DB_CONTROL + -- Database control. + do + Result := connection.db_control + end + + db_result: detachable DB_RESULT + -- Database query result. + + db_selection: detachable DB_SELECTION + -- Database selection. + + db_change: detachable DB_CHANGE + -- Database modification. + +feature -- Error handling + + check_database_change_error + -- Check database error from `db_change'. + do + if attached db_change as l_change and then not l_change.is_ok then + database_error_handler.add_database_error (l_change.error_message_32, l_change.error_code) + log.write_error (generator + ".check_database_change_error: " + l_change.error_message_32) + end + end + + check_database_selection_error + -- Check database error from `db_selection'. + do + if attached db_selection as l_selection and then not l_selection.is_ok then + database_error_handler.add_database_error (l_selection.error_message_32, l_selection.error_code) + log.write_error (generator + ".check_database_selection_error: " + l_selection.error_message_32) + end + end + feature {NODE_DATA_PROVIDER}-- Implementation connect diff --git a/persistence/implementation/common/database/database_handler_impl.e b/persistence/implementation/common/database/database_handler_impl.e index 96078ee..55bde06 100644 --- a/persistence/implementation/common/database/database_handler_impl.e +++ b/persistence/implementation/common/database/database_handler_impl.e @@ -21,7 +21,6 @@ feature {NONE} -- Initialization do connection := a_connection create last_query.make_now - set_successful ensure connection_not_void: connection /= Void last_query_not_void: last_query /= Void @@ -29,71 +28,52 @@ feature {NONE} -- Initialization feature -- Functionality - execute_reader + execute_store_reader -- Execute stored procedure that returns data. local l_db_selection: DB_SELECTION l_retried: BOOLEAN do if not l_retried then - if not keep_connection then - connect - end - if attached store as l_store then create l_db_selection.make db_selection := l_db_selection items := l_store.execute_reader (l_db_selection) + check_database_selection_error end - - if not keep_connection then - disconnect - end - set_successful log.write_debug ( generator+".execute_reader Successful") end rescue - set_last_error_from_exception ("Store procedure execution") - log.write_critical (generator+ ".execute_reader " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_selection as l_selection then + l_selection.reset + end retry end - execute_writer + execute_store_writer -- Execute stored procedure that update/add data. local l_db_change: DB_CHANGE l_retried : BOOLEAN do if not l_retried then - if not keep_connection and not is_connected then - connect - end if attached store as l_store then create l_db_change.make - db_update := l_db_change + db_change := l_db_change l_store.execute_writer (l_db_change) - if not l_store.has_error then - db_control.commit - end + check_database_change_error end - if not keep_connection then - disconnect - end - set_successful log.write_debug ( generator+".execute_writer Successful") end rescue - set_last_error_from_exception ("Store procedure execution") - log.write_critical (generator+ ".execute_writer " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_change as l_change then + l_change.reset + end retry end @@ -106,60 +86,43 @@ feature -- SQL Queries l_retried: BOOLEAN do if not l_retried then - if not keep_connection then - connect - end - if attached query as l_query then create l_db_selection.make db_selection := l_db_selection items := l_query.execute_reader (l_db_selection) + check_database_selection_error end - if not keep_connection then - disconnect - end - set_successful end rescue - set_last_error_from_exception ("execute_query") - log.write_critical (generator+ ".execute_query " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_selection as l_selection then + l_selection.reset + end retry end execute_change - -- Execute sqlquery that update/add data. + -- Execute sql_query that update/add data. local l_db_change: DB_CHANGE l_retried : BOOLEAN do if not l_retried then - if not keep_connection and not is_connected then - connect - end - if attached query as l_query then create l_db_change.make - db_update := l_db_change + db_change := l_db_change l_query.execute_change (l_db_change) - db_control.commit + check_database_change_error end - if not keep_connection then - disconnect - end - set_successful end rescue - set_last_error_from_exception ("Store procedure execution") - log.write_critical (generator+ ".execute_writer " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_change as l_change then + l_change.reset + end retry end @@ -207,24 +170,6 @@ feature -- Iteration feature {NONE} -- Implementation - connection: DATABASE_CONNECTION - -- Database connection. - - db_control: DB_CONTROL - -- Database control. - do - Result := connection.db_control - end - - db_result: detachable DB_RESULT - -- Database query result. - - db_selection: detachable DB_SELECTION - -- Database selection. - - db_update: detachable DB_CHANGE - -- Database modification. - last_query: DATE_TIME -- Last time when a query was executed. @@ -263,7 +208,7 @@ feature {NONE} -- Implementation affected_row_count: INTEGER -- The number of rows changed, deleted, or inserted by the last statement. do - if attached db_update as l_update then + if attached db_change as l_update then Result := l_update.affected_row_count end end diff --git a/persistence/implementation/common/database/database_iteration_cursor.e b/persistence/implementation/common/database/database_iteration_cursor.e index f38d844..1688b76 100644 --- a/persistence/implementation/common/database/database_iteration_cursor.e +++ b/persistence/implementation/common/database/database_iteration_cursor.e @@ -1,5 +1,5 @@ note - description: "External iteration cursor for {ESA_DATABASE_HANDLER}" + description: "External iteration cursor for {DATABASE_HANDLER}" date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $" revision: "$Revision: 95678 $" diff --git a/persistence/implementation/common/database/database_no_change_error.e b/persistence/implementation/common/database/database_no_change_error.e new file mode 100644 index 0000000..6855279 --- /dev/null +++ b/persistence/implementation/common/database/database_no_change_error.e @@ -0,0 +1,27 @@ +note + description: "Summary description for {DATABASE_NO_CHANGE_ERROR}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + DATABASE_NO_CHANGE_ERROR + +inherit + DATABASE_ERROR + redefine + make_from_message + end + +create + make_from_message + +feature {NONE} -- Init + + make_from_message (a_m: like message; a_code: like code) + -- Create from `a_m' + do + make (a_code, once "Database No Change Error", a_m) + end + +end diff --git a/persistence/implementation/common/database/database_query.e b/persistence/implementation/common/database/database_query.e index 1a5f8cd..4acec0c 100644 --- a/persistence/implementation/common/database/database_query.e +++ b/persistence/implementation/common/database/database_query.e @@ -8,14 +8,14 @@ class inherit - SHARED_ERROR + SHARED_ERROR_HANDLER REFACTORING_HELPER create data_reader -feature -- Intialization +feature {NONE} -- Intialization data_reader (a_query: STRING; a_parameters: STRING_TABLE [detachable ANY]) -- SQL data reader for the query `a_query' with arguments `a_parameters' @@ -29,6 +29,8 @@ feature -- Intialization parameters_set: parameters = a_parameters end +feature -- Execution + execute_reader (a_base_selection: DB_SELECTION): detachable LIST [DB_RESULT] -- Execute the Current sql query. do @@ -42,7 +44,6 @@ feature -- Intialization a_base_selection.load_result Result := a_base_selection.container else - set_last_error (a_base_selection.error_message_32, generator + ".execute_reader" ) log.write_error (generator + "." + a_base_selection.error_message_32) end unset_map_name (a_base_selection) @@ -50,17 +51,12 @@ feature -- Intialization end execute_change (a_base_change: DB_CHANGE) - -- Execute the Current sql query . + -- Execute the Current sql query to change/update data in the database. do to_implement ("Check test dynamic sequel. to redesign.") set_map_name (a_base_change) a_base_change.set_query (query) a_base_change.execute_query - if a_base_change.is_ok then - else - set_last_error (a_base_change.error_message_32, generator + ".execute_reader" ) - log.write_error (generator + "." + a_base_change.error_message_32) - end unset_map_name (a_base_change) end @@ -72,17 +68,6 @@ feature -- Access parameters: STRING_TABLE [detachable ANY] -- query parameters. -feature -- Status Report - - has_error: BOOLEAN - -- is there an error? - - error_message: detachable STRING_32 - -- Error message if any. - - error_code: INTEGER - -- Error code. - feature {NONE} -- Implementation set_map_name (a_base_selection: DB_EXPRESSION) @@ -140,4 +125,4 @@ feature {NONE} -- Implementation end -end -- ESA_DATABASE_QUERY +end -- DATABASE_QUERY diff --git a/persistence/implementation/common/database/error/database_error.e b/persistence/implementation/common/database/error/database_error.e new file mode 100644 index 0000000..2dcd646 --- /dev/null +++ b/persistence/implementation/common/database/error/database_error.e @@ -0,0 +1,23 @@ +note + description: "Error from database" + date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" + revision: "$Revision: 195 $" + +class + DATABASE_ERROR + +inherit + ERROR_CUSTOM + +create + make_from_message + +feature {NONE} -- Init + + make_from_message (a_m: like message; a_code: like code) + -- Create from `a_m' + do + make (a_code, once "Database Error", a_m) + end + +end diff --git a/persistence/implementation/common/database/database_error_handler.e b/persistence/implementation/common/database/error/database_error_handler.e similarity index 60% rename from persistence/implementation/common/database/database_error_handler.e rename to persistence/implementation/common/database/error/database_error_handler.e index a2718fe..5af3545 100644 --- a/persistence/implementation/common/database/database_error_handler.e +++ b/persistence/implementation/common/database/error/database_error_handler.e @@ -15,21 +15,21 @@ create feature -- Error operation add_database_error (a_message: READABLE_STRING_32; a_code: INTEGER) - -- Add a database error + -- Add a database error. local --- l_error: DATABASE_ERROR + l_error: DATABASE_ERROR do --- create l_error.make_from_message (a_message, a_code) --- add_error (l_error) + create l_error.make_from_message (a_message, a_code) + add_error (l_error) end add_database_no_change_error (a_message: READABLE_STRING_32; a_code: INTEGER) - -- Add a database error + -- Add a database error. local --- l_error: DATABASE_NO_CHANGE_ERROR + l_error: DATABASE_NO_CHANGE_ERROR do --- create l_error.make_from_message (a_message, a_code) --- add_error (l_error) + create l_error.make_from_message (a_message, a_code) + add_error (l_error) end end diff --git a/persistence/implementation/common/database/shared_error_handler.e b/persistence/implementation/common/database/error/shared_error_handler.e similarity index 78% rename from persistence/implementation/common/database/shared_error_handler.e rename to persistence/implementation/common/database/error/shared_error_handler.e index 9c26bfd..15c06c1 100644 --- a/persistence/implementation/common/database/shared_error_handler.e +++ b/persistence/implementation/common/database/error/shared_error_handler.e @@ -6,14 +6,26 @@ note class SHARED_ERROR_HANDLER +inherit + + SHARED_LOGGER + feature -- Access database_error_handler: DATABASE_ERROR_HANDLER - -- Error handler + -- Error handler. once create Result.make end +feature -- Status Report + + has_error: BOOLEAN + -- Has error? + do + Result := database_error_handler.has_error + end + feature -- Helper exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) diff --git a/persistence/implementation/mysql/src/cms_storage_mysql.e b/persistence/implementation/mysql/src/cms_storage_mysql.e index 74a72ce..47b74ca 100644 --- a/persistence/implementation/mysql/src/cms_storage_mysql.e +++ b/persistence/implementation/mysql/src/cms_storage_mysql.e @@ -21,6 +21,7 @@ feature {NONE} -- Initialization require is_connected: a_connection.is_connected do + connection := a_connection log.write_information (generator+".make_with_database is database connected? "+ a_connection.is_connected.out ) create node_provider.make (a_connection) create user_provider.make (a_connection) @@ -125,11 +126,14 @@ feature -- Change: user save_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 + connection.begin_transaction user_provider.new_user (a_user.name, l_password, l_email) + connection.commit else set_last_error ("User or Password not attached", generator + ".save_user") end @@ -282,4 +286,6 @@ feature {NONE} -- Post process user_provider: USER_DATA_PROVIDER -- User Data provider. + connection: DATABASE_CONNECTION + -- Current database connection. end diff --git a/persistence/implementation/mysql/src/database/database_connection_mysql.e b/persistence/implementation/mysql/src/database/database_connection_mysql.e index bc5f890..b9d173f 100644 --- a/persistence/implementation/mysql/src/database/database_connection_mysql.e +++ b/persistence/implementation/mysql/src/database/database_connection_mysql.e @@ -34,17 +34,11 @@ feature -- Initialization if keep_connection then connect end - set_successful else create db_control.make end rescue - create db_control.make - set_last_error_from_exception ("Connection execution") - log.write_critical (generator + ".make_common:" + last_error_message) - if is_connected then - disconnect - end + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) l_retried := True retry end @@ -66,17 +60,11 @@ feature -- Initialization if keep_connection then connect end - set_successful else create db_control.make end rescue - create db_control.make - set_last_error_from_exception ("Connection execution") - log.write_critical (generator + ".make_common:" + last_error_message) - if is_connected then - disconnect - end + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) l_retried := True retry end diff --git a/persistence/implementation/mysql/src/provider/node_data_provider.e b/persistence/implementation/mysql/src/provider/node_data_provider.e index 3bcfc84..59c9bae 100644 --- a/persistence/implementation/mysql/src/provider/node_data_provider.e +++ b/persistence/implementation/mysql/src/provider/node_data_provider.e @@ -34,7 +34,6 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do - Result := db_handler.successful end feature -- Access @@ -481,13 +480,6 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do - if db_handler.successful then - set_successful - else - if attached db_handler.last_error then - set_last_error_from_handler (db_handler.last_error) - end - end end end diff --git a/persistence/implementation/mysql/src/provider/role_data_provider.e b/persistence/implementation/mysql/src/provider/role_data_provider.e index 61590a0..8e82a64 100644 --- a/persistence/implementation/mysql/src/provider/role_data_provider.e +++ b/persistence/implementation/mysql/src/provider/role_data_provider.e @@ -35,7 +35,7 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do - Result := db_handler.successful +-- Result := db_handler.successful end has_roles: BOOLEAN @@ -210,13 +210,7 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do - if db_handler.successful then - set_successful - else - if attached db_handler.last_error then - set_last_error_from_handler (db_handler.last_error) - end - end + end end diff --git a/persistence/implementation/mysql/src/provider/user_data_provider.e b/persistence/implementation/mysql/src/provider/user_data_provider.e index a1ac47b..0d9b0bf 100644 --- a/persistence/implementation/mysql/src/provider/user_data_provider.e +++ b/persistence/implementation/mysql/src/provider/user_data_provider.e @@ -34,7 +34,6 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do - Result := db_handler.successful end has_user: BOOLEAN @@ -311,13 +310,6 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do - if db_handler.successful then - set_successful - else - if attached db_handler.last_error then - set_last_error_from_handler (db_handler.last_error) - end - end end end diff --git a/persistence/implementation/mysql/tests/util/clean_db.e b/persistence/implementation/mysql/tests/util/clean_db.e index 965465f..dce7176 100644 --- a/persistence/implementation/mysql/tests/util/clean_db.e +++ b/persistence/implementation/mysql/tests/util/clean_db.e @@ -24,6 +24,7 @@ feature do create l_parameters.make (0) + a_connection.begin_transaction -- Clean Profiles db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Sql_delete_user_profiles, l_parameters)) @@ -72,6 +73,7 @@ feature db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Rest_profiles_autoincrement, l_parameters)) db_handler(a_connection).execute_change + a_connection.commit end From 609d71a0e9d8b2c0ac9fa56e430c1bfba8687dec Mon Sep 17 00:00:00 2001 From: jvelilla Date: Mon, 13 Oct 2014 18:45:45 -0300 Subject: [PATCH 03/20] Added nested transaction support. Added test cases showing transaction support scenarios. --- .../common/database/database_connection.e | 136 ++++++++++++++ .../tests/transactions/transaction_test_set.e | 168 ++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 persistence/implementation/mysql/tests/transactions/transaction_test_set.e diff --git a/persistence/implementation/common/database/database_connection.e b/persistence/implementation/common/database/database_connection.e index cfb9fd9..a6c2d2c 100644 --- a/persistence/implementation/common/database/database_connection.e +++ b/persistence/implementation/common/database/database_connection.e @@ -131,6 +131,142 @@ feature -- Transactions retry end + +feature -- + + is_connected_to_storage: BOOLEAN + -- Is connected to the database + do + Result := db_control.is_connected + end + +feature -- Transaction Status + + in_transaction_session: BOOLEAN + -- Is session started? + + transaction_session_depth: INTEGER + -- Depth in the transaction session + +feature -- Transaction Operation + + begin_transaction2 + -- Start session + -- if already started, increase the `transaction_session_depth' + require + in_transaction_session implies transaction_session_depth > 0 + not in_transaction_session implies transaction_session_depth = 0 + local + l_session_control: like db_control + l_retried: INTEGER + do + if l_retried = 0 then + if not in_transaction_session then + database_error_handler.reset + + check transaction_session_depth = 0 end + + debug ("database_session") + print ("..Start session%N") + end + connect -- connect the DB + if is_connected_to_storage then + in_transaction_session := True + db_control.begin -- start transaction + else + l_session_control := db_control + if not l_session_control.is_ok then + database_error_handler.add_database_error (l_session_control.error_message_32, l_session_control.error_code) + else + database_error_handler.add_database_error ("Session_not_started_error_message", 0) + end + l_session_control.reset + end + end + transaction_session_depth := transaction_session_depth + 1 + else + if l_retried = 1 then + transaction_session_depth := transaction_session_depth + 1 + if attached (create {EXCEPTION_MANAGER}).last_exception as e then + if attached {ASSERTION_VIOLATION} e then + --| Ignore for now with MYSQL ... + else + exception_as_error (e) + end + end + + in_transaction_session := False + db_control.reset + else + in_transaction_session := False + end + end + ensure + transaction_session_depth = (old transaction_session_depth) + 1 + rescue + l_retried := l_retried + 1 + retry + end + + commit2 + -- End session + local + l_retried: BOOLEAN + do + if not l_retried then + transaction_session_depth := transaction_session_depth - 1 + if transaction_session_depth = 0 then + debug ("database_session") + print ("..End session%N") + end + if is_connected_to_storage then + if not database_error_handler.has_error then + db_control.commit -- Commit transaction + else + db_control.rollback -- Rollback transaction + end + end + in_transaction_session := False + end + else + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + in_transaction_session := False + transaction_session_depth := transaction_session_depth - 1 + db_control.reset + end + rescue + l_retried := True + retry + end + + + + rollback2 + -- End session + local + l_retried: BOOLEAN + do + if not l_retried then + transaction_session_depth := transaction_session_depth - 1 + if transaction_session_depth = 0 then + debug ("database_session") + print ("..End session%N") + end + if is_connected_to_storage then + db_control.rollback -- Rollback transaction + end + in_transaction_session := False + end + else + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + in_transaction_session := False + transaction_session_depth := transaction_session_depth - 1 + db_control.reset + end + rescue + l_retried := True + retry + end feature -- Change Element not_keep_connection diff --git a/persistence/implementation/mysql/tests/transactions/transaction_test_set.e b/persistence/implementation/mysql/tests/transactions/transaction_test_set.e new file mode 100644 index 0000000..3199f71 --- /dev/null +++ b/persistence/implementation/mysql/tests/transactions/transaction_test_set.e @@ -0,0 +1,168 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + TRANSACTION_TEST_SET + +inherit + + EQA_TEST_SET + redefine + on_prepare, + on_clean + select + default_create + end + ABSTRACT_DB_TEST + rename + default_create as default_db_test + end + + +feature {NONE} -- Events + + on_prepare + -- + do + (create {CLEAN_DB}).clean_db(connection) + end + + on_clean + -- + do + end + +feature -- Test routines + + test_user_rollback + note + testing: "execution/isolated" + do + connection.begin_transaction + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + connection.rollback + assert ("Not has user:", not user_provider.has_user) + end + + test_user_node_rollback + note + testing: "execution/isolated" + do + connection.begin_transaction + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + node_provider.add_author (1, 1) + assert ("Has one node:", node_provider.count = 1) + connection.rollback + assert ("Not has user:", not user_provider.has_user) + assert ("Not has nodes:", node_provider.count = 0) + end + + + + test_user_node_nested_transaction_with_rollback_not_supported + note + testing: "execution/isolated" + do + connection.begin_transaction2 + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + assert ("Has one node:", node_provider.count = 1) + + connection.begin_transaction2 + user_provider.new_user ("test1", "test1","test1@admin.com") + assert ("Has user: test1", attached user_provider.user_by_name ("test1")) + connection.rollback2 + + connection.commit2 + assert ("Has user test:", attached user_provider.user_by_name ("test")) + assert ("Has nodes:", node_provider.count = 1) + assert ("Not has user: test1", user_provider.user_by_name ("test1") = Void) + end + + + test_user_node_nested_transaction_with_commit + note + testing: "execution/isolated" + do + connection.begin_transaction2 + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + assert ("Has one node:", node_provider.count = 1) + + connection.begin_transaction2 + user_provider.new_user ("test1", "test1","test1@admin.com") + assert ("Has user: test1", attached user_provider.user_by_name ("test1")) + connection.commit2 + + connection.commit2 + assert ("Has user test:", attached user_provider.user_by_name ("test")) + assert ("Has user test1:", attached user_provider.user_by_name ("test1")) + assert ("Has nodes:", node_provider.count = 1) + end + + + test_user_node_nested_transaction_with_rollback + note + testing: "execution/isolated" + do + connection.begin_transaction2 + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + assert ("Has one node:", node_provider.count = 1) + + connection.begin_transaction2 + user_provider.new_user ("test1", "test1","test1@admin.com") + assert ("Has user: test1", attached user_provider.user_by_name ("test1")) + connection.commit2 + + connection.rollback2 + assert ("Not Has user test:", user_provider.user_by_name ("test") = void) + assert ("Not Has user test1:", user_provider.user_by_name ("test1") = void) + assert ("Has 0 nodes:", node_provider.count = 0) + end + + + + + +feature {NONE} -- Implementation + + node_provider: NODE_DATA_PROVIDER + -- node provider. + once + create Result.make (connection) + end + + user_provider: USER_DATA_PROVIDER + -- user provider. + once + create Result.make (connection) + end + + +feature {NONE} -- Implementation Fixture Factories + + default_node: CMS_NODE + do + Result := custom_node ("Default content", "default summary", "Default") + end + + custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_NODE + do + create Result.make (a_content, a_summary, a_title) + end +end + + From b8257e7bf07bc69be223cffa87256208e4be76ae Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 8 Oct 2014 16:33:41 -0300 Subject: [PATCH 04/20] Clean code: removed unused variables. Move BASIC_AUTH module to ROC_SERVER setup, as an example of module extension --- cms/src/configuration/cms_default_setup.e | 4 ---- cms/src/modules/basic_auth/handler/basic_auth_login_handler.e | 2 -- cms/src/modules/node/handler/node_content_handler.e | 3 --- cms/src/modules/node/handler/node_handler.e | 1 - cms/src/modules/node/handler/node_summary_handler.e | 2 -- cms/src/modules/node/handler/node_title_handler.e | 2 -- cms/src/service/cms_api_service.e | 2 -- cms/src/service/response/cms_generic_response.e | 1 - examples/roc_api/src/ewf_roc_server.e | 3 +-- 9 files changed, 1 insertion(+), 19 deletions(-) diff --git a/cms/src/configuration/cms_default_setup.e b/cms/src/configuration/cms_default_setup.e index e1bf624..8918a36 100644 --- a/cms/src/configuration/cms_default_setup.e +++ b/cms/src/configuration/cms_default_setup.e @@ -62,10 +62,6 @@ feature {NONE} -- Initialization -- modules.extend (m) - create {BASIC_AUTH_MODULE} m.make (Current) - m.enable - modules.extend (m) - create {NODE_MODULE} m.make (Current) m.enable modules.extend (m) diff --git a/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e b/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e index a0e6df8..4035e0f 100644 --- a/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e +++ b/cms/src/modules/basic_auth/handler/basic_auth_login_handler.e @@ -47,8 +47,6 @@ feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - l_page: CMS_RESPONSE do log.write_information(generator + ".do_get Processing basic auth login") if attached {STRING_32} current_user_name (req) as l_user then diff --git a/cms/src/modules/node/handler/node_content_handler.e b/cms/src/modules/node/handler/node_content_handler.e index a7113b7..31b911a 100644 --- a/cms/src/modules/node/handler/node_content_handler.e +++ b/cms/src/modules/node/handler/node_content_handler.e @@ -88,8 +88,6 @@ feature -- HTTP Methods do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - l_page: CMS_RESPONSE do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then @@ -116,7 +114,6 @@ feature -- HTTP Methods -- local u_node: CMS_NODE - l_page: CMS_RESPONSE do to_implement ("Check if user has permissions") if attached current_user (req) as l_user then diff --git a/cms/src/modules/node/handler/node_handler.e b/cms/src/modules/node/handler/node_handler.e index e9d789f..e4257b6 100644 --- a/cms/src/modules/node/handler/node_handler.e +++ b/cms/src/modules/node/handler/node_handler.e @@ -85,7 +85,6 @@ feature -- HTTP Methods -- local u_node: CMS_NODE - l_page: CMS_RESPONSE do to_implement ("Check user permissions!!!") if attached current_user (req) as l_user then diff --git a/cms/src/modules/node/handler/node_summary_handler.e b/cms/src/modules/node/handler/node_summary_handler.e index d3ec258..96f3c36 100644 --- a/cms/src/modules/node/handler/node_summary_handler.e +++ b/cms/src/modules/node/handler/node_summary_handler.e @@ -87,8 +87,6 @@ feature -- HTTP Methods do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - u_node: CMS_NODE do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then diff --git a/cms/src/modules/node/handler/node_title_handler.e b/cms/src/modules/node/handler/node_title_handler.e index 570b155..a5dfe9d 100644 --- a/cms/src/modules/node/handler/node_title_handler.e +++ b/cms/src/modules/node/handler/node_title_handler.e @@ -86,8 +86,6 @@ feature -- HTTP Methods do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- - local - u_node: CMS_NODE do if attached current_user_name (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then diff --git a/cms/src/service/cms_api_service.e b/cms/src/service/cms_api_service.e index c7b69ff..a7d4c8f 100644 --- a/cms/src/service/cms_api_service.e +++ b/cms/src/service/cms_api_service.e @@ -29,8 +29,6 @@ feature -- Initialize feature -- Access is_valid_credential (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 diff --git a/cms/src/service/response/cms_generic_response.e b/cms/src/service/response/cms_generic_response.e index 380a391..371bc05 100644 --- a/cms/src/service/response/cms_generic_response.e +++ b/cms/src/service/response/cms_generic_response.e @@ -50,7 +50,6 @@ feature -- Responses -- Handle not authorized. local h: HTTP_HEADER - output: STRING do create h.make h.put_content_type_text_html diff --git a/examples/roc_api/src/ewf_roc_server.e b/examples/roc_api/src/ewf_roc_server.e index 4919a54..5fd497b 100644 --- a/examples/roc_api/src/ewf_roc_server.e +++ b/examples/roc_api/src/ewf_roc_server.e @@ -117,7 +117,6 @@ feature -- CMS Initialization initialize_cms (a_setup: CMS_SETUP) local cms: CMS_SERVICE - l_modules: CMS_MODULE_COLLECTION do log.write_debug (generator + ".initialize_cms") @@ -134,7 +133,7 @@ feature -- CMS setup local m: CMS_MODULE do - create {NODE_MODULE} m.make (a_setup) + create {BASIC_AUTH_MODULE} m.make (a_setup) m.enable a_setup.modules.extend (m) From 4b9a692c2cb8c5f197d4d1c18ff4acbd7072b116 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Thu, 9 Oct 2014 10:01:49 -0300 Subject: [PATCH 05/20] Initial Import: Database transaction handling. Initial Import: Error handling using ewf error library. Added a CMS_ERROR_FILTER as part of registered filters of CMS_SERVICE --- cms/cms-safe.ecf | 1 + cms/src/configuration/cms_default_setup.e | 40 ++++++- cms/src/configuration/cms_setup.e | 6 + cms/src/service/cms_service.e | 6 + cms/src/service/filter/cms_error_filter.e | 33 ++++++ .../common/database/database_connection.e | 61 +++++++++- .../common/database/database_handler.e | 55 +++++++-- .../common/database/database_handler_impl.e | 107 +++++------------- .../database/database_iteration_cursor.e | 2 +- .../database/database_no_change_error.e | 27 +++++ .../common/database/database_query.e | 27 +---- .../common/database/error/database_error.e | 23 ++++ .../{ => error}/database_error_handler.e | 16 +-- .../{ => error}/shared_error_handler.e | 14 ++- .../mysql/src/cms_storage_mysql.e | 6 + .../src/database/database_connection_mysql.e | 16 +-- .../mysql/src/provider/node_data_provider.e | 8 -- .../mysql/src/provider/role_data_provider.e | 10 +- .../mysql/src/provider/user_data_provider.e | 8 -- .../mysql/tests/util/clean_db.e | 2 + 20 files changed, 301 insertions(+), 167 deletions(-) create mode 100644 cms/src/service/filter/cms_error_filter.e create mode 100644 persistence/implementation/common/database/database_no_change_error.e create mode 100644 persistence/implementation/common/database/error/database_error.e rename persistence/implementation/common/database/{ => error}/database_error_handler.e (60%) rename persistence/implementation/common/database/{ => error}/shared_error_handler.e (78%) diff --git a/cms/cms-safe.ecf b/cms/cms-safe.ecf index 235bd74..5da317c 100644 --- a/cms/cms-safe.ecf +++ b/cms/cms-safe.ecf @@ -10,6 +10,7 @@ + diff --git a/cms/src/configuration/cms_default_setup.e b/cms/src/configuration/cms_default_setup.e index 8918a36..eabc20c 100644 --- a/cms/src/configuration/cms_default_setup.e +++ b/cms/src/configuration/cms_default_setup.e @@ -17,6 +17,7 @@ feature {NONE} -- Initialization make (a_layout: CMS_LAYOUT) do + create error_handler.make layout := a_layout create configuration.make (layout) initialize @@ -28,7 +29,6 @@ feature {NONE} -- Initialization create modules.make (3) build_api_service build_mailer - initialize_modules end @@ -61,7 +61,6 @@ feature {NONE} -- Initialization -- m.enable -- modules.extend (m) - create {NODE_MODULE} m.make (Current) m.enable modules.extend (m) @@ -89,15 +88,44 @@ feature -- Access build_api_service local l_database: DATABASE_CONNECTION + l_retry: BOOLEAN + l_message: STRING do - to_implement ("Refactor database setup") - if attached (create {JSON_CONFIGURATION}).new_database_configuration (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 api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database)) + if not l_retry then + to_implement ("Refactor database setup") + if attached (create {JSON_CONFIGURATION}).new_database_configuration (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 api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database)) + else + create {DATABASE_CONNECTION_NULL} l_database.make_common + create api_service.make (create {CMS_STORAGE_NULL}) + 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 api_service.make (create {CMS_STORAGE_NULL}) + 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 + l_retry := True + retry end build_auth_engine diff --git a/cms/src/configuration/cms_setup.e b/cms/src/configuration/cms_setup.e index f0af327..0e6189d 100644 --- a/cms/src/configuration/cms_setup.e +++ b/cms/src/configuration/cms_setup.e @@ -32,6 +32,12 @@ feature -- Access deferred end + +feature -- Status Report + + error_handler: ERROR_HANDLER + -- Error handler. + feature -- Access: Site site_id: READABLE_STRING_8 diff --git a/cms/src/service/cms_service.e b/cms/src/service/cms_service.e index 37a4759..84b67e6 100644 --- a/cms/src/service/cms_service.e +++ b/cms/src/service/cms_service.e @@ -165,9 +165,15 @@ feature -- Filters do log.write_debug (generator + ".create_filter") l_filter := Void + -- Maintenance create {WSF_MAINTENANCE_FILTER} f f.set_next (l_filter) + l_filter := f + + -- Error Filter + create {CMS_ERROR_FILTER} f.make (setup) + f.set_next (l_filter) l_filter := f -- Include filters from modules diff --git a/cms/src/service/filter/cms_error_filter.e b/cms/src/service/filter/cms_error_filter.e new file mode 100644 index 0000000..8a2f154 --- /dev/null +++ b/cms/src/service/filter/cms_error_filter.e @@ -0,0 +1,33 @@ +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 setup.error_handler.has_error then + log.write_information (generator + ".execute") + execute_next (req, res) + else + log.write_critical (generator + ".execute" + setup.error_handler.as_string_representation ) + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + setup.error_handler.reset + end + end + +end diff --git a/persistence/implementation/common/database/database_connection.e b/persistence/implementation/common/database/database_connection.e index 7591273..cfb9fd9 100644 --- a/persistence/implementation/common/database/database_connection.e +++ b/persistence/implementation/common/database/database_connection.e @@ -10,7 +10,7 @@ inherit DATABASE_CONFIG - SHARED_ERROR + SHARED_ERROR_HANDLER feature {NONE} -- Initialization @@ -72,6 +72,65 @@ feature -- Database Setup keep_connection: BOOLEAN -- Keep connection alive? +feature -- Transactions + + begin_transaction + -- Start a transaction which will be terminated by a call to `rollback' or `commit'. + local + rescued: BOOLEAN + do + if not rescued then + if db_control.is_ok then + db_control.begin + else + database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code) + end + end + rescue + rescued := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + db_control.reset + retry + end + + commit + -- Commit updates in the database. + local + rescued: BOOLEAN + do + if not rescued then + if db_control.is_ok then + db_control.commit + else + database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code) + end + end + rescue + rescued := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + db_control.reset + retry + end + + rollback + -- Rollback updates in the database. + local + rescued: BOOLEAN + do + if not rescued then + if db_control.is_ok then + db_control.rollback + else + database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code) + end + end + rescue + rescued := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + db_control.reset + retry + end + feature -- Change Element not_keep_connection diff --git a/persistence/implementation/common/database/database_handler.e b/persistence/implementation/common/database/database_handler.e index 3551e4a..875b7a7 100644 --- a/persistence/implementation/common/database/database_handler.e +++ b/persistence/implementation/common/database/database_handler.e @@ -8,7 +8,7 @@ deferred class inherit - SHARED_ERROR + SHARED_ERROR_HANDLER feature -- Access @@ -42,15 +42,15 @@ feature -- Modifiers feature -- Functionality Store Procedures - execute_reader - -- Execute store. + execute_store_reader + -- Execute a `store' to read data. require store_not_void: store /= void deferred end - execute_writer - -- Execute store. + execute_store_writer + -- Execute a `store' to write data. require store_not_void: store /= void deferred @@ -59,14 +59,14 @@ feature -- Functionality Store Procedures feature -- SQL Queries execute_query - -- Execute query. + -- Execute sql query, the read data from the database. require query_not_void: query /= void deferred end execute_change - -- Execute sqlquery that update/add data. + -- Execute sql query that update/add data. require query_not_void: query /= void deferred @@ -147,14 +147,49 @@ feature -- Access feature -- Status Report - has_error: BOOLEAN - -- Is there an error? - count: INTEGER -- Number of rows, last execution. deferred end + connection: DATABASE_CONNECTION + -- Database connection. + + db_control: DB_CONTROL + -- Database control. + do + Result := connection.db_control + end + + db_result: detachable DB_RESULT + -- Database query result. + + db_selection: detachable DB_SELECTION + -- Database selection. + + db_change: detachable DB_CHANGE + -- Database modification. + +feature -- Error handling + + check_database_change_error + -- Check database error from `db_change'. + do + if attached db_change as l_change and then not l_change.is_ok then + database_error_handler.add_database_error (l_change.error_message_32, l_change.error_code) + log.write_error (generator + ".check_database_change_error: " + l_change.error_message_32) + end + end + + check_database_selection_error + -- Check database error from `db_selection'. + do + if attached db_selection as l_selection and then not l_selection.is_ok then + database_error_handler.add_database_error (l_selection.error_message_32, l_selection.error_code) + log.write_error (generator + ".check_database_selection_error: " + l_selection.error_message_32) + end + end + feature {NODE_DATA_PROVIDER}-- Implementation connect diff --git a/persistence/implementation/common/database/database_handler_impl.e b/persistence/implementation/common/database/database_handler_impl.e index 96078ee..55bde06 100644 --- a/persistence/implementation/common/database/database_handler_impl.e +++ b/persistence/implementation/common/database/database_handler_impl.e @@ -21,7 +21,6 @@ feature {NONE} -- Initialization do connection := a_connection create last_query.make_now - set_successful ensure connection_not_void: connection /= Void last_query_not_void: last_query /= Void @@ -29,71 +28,52 @@ feature {NONE} -- Initialization feature -- Functionality - execute_reader + execute_store_reader -- Execute stored procedure that returns data. local l_db_selection: DB_SELECTION l_retried: BOOLEAN do if not l_retried then - if not keep_connection then - connect - end - if attached store as l_store then create l_db_selection.make db_selection := l_db_selection items := l_store.execute_reader (l_db_selection) + check_database_selection_error end - - if not keep_connection then - disconnect - end - set_successful log.write_debug ( generator+".execute_reader Successful") end rescue - set_last_error_from_exception ("Store procedure execution") - log.write_critical (generator+ ".execute_reader " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_selection as l_selection then + l_selection.reset + end retry end - execute_writer + execute_store_writer -- Execute stored procedure that update/add data. local l_db_change: DB_CHANGE l_retried : BOOLEAN do if not l_retried then - if not keep_connection and not is_connected then - connect - end if attached store as l_store then create l_db_change.make - db_update := l_db_change + db_change := l_db_change l_store.execute_writer (l_db_change) - if not l_store.has_error then - db_control.commit - end + check_database_change_error end - if not keep_connection then - disconnect - end - set_successful log.write_debug ( generator+".execute_writer Successful") end rescue - set_last_error_from_exception ("Store procedure execution") - log.write_critical (generator+ ".execute_writer " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_change as l_change then + l_change.reset + end retry end @@ -106,60 +86,43 @@ feature -- SQL Queries l_retried: BOOLEAN do if not l_retried then - if not keep_connection then - connect - end - if attached query as l_query then create l_db_selection.make db_selection := l_db_selection items := l_query.execute_reader (l_db_selection) + check_database_selection_error end - if not keep_connection then - disconnect - end - set_successful end rescue - set_last_error_from_exception ("execute_query") - log.write_critical (generator+ ".execute_query " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_selection as l_selection then + l_selection.reset + end retry end execute_change - -- Execute sqlquery that update/add data. + -- Execute sql_query that update/add data. local l_db_change: DB_CHANGE l_retried : BOOLEAN do if not l_retried then - if not keep_connection and not is_connected then - connect - end - if attached query as l_query then create l_db_change.make - db_update := l_db_change + db_change := l_db_change l_query.execute_change (l_db_change) - db_control.commit + check_database_change_error end - if not keep_connection then - disconnect - end - set_successful end rescue - set_last_error_from_exception ("Store procedure execution") - log.write_critical (generator+ ".execute_writer " + last_error_message) - if is_connected then - disconnect - end l_retried := True + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + if attached db_change as l_change then + l_change.reset + end retry end @@ -207,24 +170,6 @@ feature -- Iteration feature {NONE} -- Implementation - connection: DATABASE_CONNECTION - -- Database connection. - - db_control: DB_CONTROL - -- Database control. - do - Result := connection.db_control - end - - db_result: detachable DB_RESULT - -- Database query result. - - db_selection: detachable DB_SELECTION - -- Database selection. - - db_update: detachable DB_CHANGE - -- Database modification. - last_query: DATE_TIME -- Last time when a query was executed. @@ -263,7 +208,7 @@ feature {NONE} -- Implementation affected_row_count: INTEGER -- The number of rows changed, deleted, or inserted by the last statement. do - if attached db_update as l_update then + if attached db_change as l_update then Result := l_update.affected_row_count end end diff --git a/persistence/implementation/common/database/database_iteration_cursor.e b/persistence/implementation/common/database/database_iteration_cursor.e index f38d844..1688b76 100644 --- a/persistence/implementation/common/database/database_iteration_cursor.e +++ b/persistence/implementation/common/database/database_iteration_cursor.e @@ -1,5 +1,5 @@ note - description: "External iteration cursor for {ESA_DATABASE_HANDLER}" + description: "External iteration cursor for {DATABASE_HANDLER}" date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $" revision: "$Revision: 95678 $" diff --git a/persistence/implementation/common/database/database_no_change_error.e b/persistence/implementation/common/database/database_no_change_error.e new file mode 100644 index 0000000..6855279 --- /dev/null +++ b/persistence/implementation/common/database/database_no_change_error.e @@ -0,0 +1,27 @@ +note + description: "Summary description for {DATABASE_NO_CHANGE_ERROR}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + DATABASE_NO_CHANGE_ERROR + +inherit + DATABASE_ERROR + redefine + make_from_message + end + +create + make_from_message + +feature {NONE} -- Init + + make_from_message (a_m: like message; a_code: like code) + -- Create from `a_m' + do + make (a_code, once "Database No Change Error", a_m) + end + +end diff --git a/persistence/implementation/common/database/database_query.e b/persistence/implementation/common/database/database_query.e index 1a5f8cd..4acec0c 100644 --- a/persistence/implementation/common/database/database_query.e +++ b/persistence/implementation/common/database/database_query.e @@ -8,14 +8,14 @@ class inherit - SHARED_ERROR + SHARED_ERROR_HANDLER REFACTORING_HELPER create data_reader -feature -- Intialization +feature {NONE} -- Intialization data_reader (a_query: STRING; a_parameters: STRING_TABLE [detachable ANY]) -- SQL data reader for the query `a_query' with arguments `a_parameters' @@ -29,6 +29,8 @@ feature -- Intialization parameters_set: parameters = a_parameters end +feature -- Execution + execute_reader (a_base_selection: DB_SELECTION): detachable LIST [DB_RESULT] -- Execute the Current sql query. do @@ -42,7 +44,6 @@ feature -- Intialization a_base_selection.load_result Result := a_base_selection.container else - set_last_error (a_base_selection.error_message_32, generator + ".execute_reader" ) log.write_error (generator + "." + a_base_selection.error_message_32) end unset_map_name (a_base_selection) @@ -50,17 +51,12 @@ feature -- Intialization end execute_change (a_base_change: DB_CHANGE) - -- Execute the Current sql query . + -- Execute the Current sql query to change/update data in the database. do to_implement ("Check test dynamic sequel. to redesign.") set_map_name (a_base_change) a_base_change.set_query (query) a_base_change.execute_query - if a_base_change.is_ok then - else - set_last_error (a_base_change.error_message_32, generator + ".execute_reader" ) - log.write_error (generator + "." + a_base_change.error_message_32) - end unset_map_name (a_base_change) end @@ -72,17 +68,6 @@ feature -- Access parameters: STRING_TABLE [detachable ANY] -- query parameters. -feature -- Status Report - - has_error: BOOLEAN - -- is there an error? - - error_message: detachable STRING_32 - -- Error message if any. - - error_code: INTEGER - -- Error code. - feature {NONE} -- Implementation set_map_name (a_base_selection: DB_EXPRESSION) @@ -140,4 +125,4 @@ feature {NONE} -- Implementation end -end -- ESA_DATABASE_QUERY +end -- DATABASE_QUERY diff --git a/persistence/implementation/common/database/error/database_error.e b/persistence/implementation/common/database/error/database_error.e new file mode 100644 index 0000000..2dcd646 --- /dev/null +++ b/persistence/implementation/common/database/error/database_error.e @@ -0,0 +1,23 @@ +note + description: "Error from database" + date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" + revision: "$Revision: 195 $" + +class + DATABASE_ERROR + +inherit + ERROR_CUSTOM + +create + make_from_message + +feature {NONE} -- Init + + make_from_message (a_m: like message; a_code: like code) + -- Create from `a_m' + do + make (a_code, once "Database Error", a_m) + end + +end diff --git a/persistence/implementation/common/database/database_error_handler.e b/persistence/implementation/common/database/error/database_error_handler.e similarity index 60% rename from persistence/implementation/common/database/database_error_handler.e rename to persistence/implementation/common/database/error/database_error_handler.e index a2718fe..5af3545 100644 --- a/persistence/implementation/common/database/database_error_handler.e +++ b/persistence/implementation/common/database/error/database_error_handler.e @@ -15,21 +15,21 @@ create feature -- Error operation add_database_error (a_message: READABLE_STRING_32; a_code: INTEGER) - -- Add a database error + -- Add a database error. local --- l_error: DATABASE_ERROR + l_error: DATABASE_ERROR do --- create l_error.make_from_message (a_message, a_code) --- add_error (l_error) + create l_error.make_from_message (a_message, a_code) + add_error (l_error) end add_database_no_change_error (a_message: READABLE_STRING_32; a_code: INTEGER) - -- Add a database error + -- Add a database error. local --- l_error: DATABASE_NO_CHANGE_ERROR + l_error: DATABASE_NO_CHANGE_ERROR do --- create l_error.make_from_message (a_message, a_code) --- add_error (l_error) + create l_error.make_from_message (a_message, a_code) + add_error (l_error) end end diff --git a/persistence/implementation/common/database/shared_error_handler.e b/persistence/implementation/common/database/error/shared_error_handler.e similarity index 78% rename from persistence/implementation/common/database/shared_error_handler.e rename to persistence/implementation/common/database/error/shared_error_handler.e index 9c26bfd..15c06c1 100644 --- a/persistence/implementation/common/database/shared_error_handler.e +++ b/persistence/implementation/common/database/error/shared_error_handler.e @@ -6,14 +6,26 @@ note class SHARED_ERROR_HANDLER +inherit + + SHARED_LOGGER + feature -- Access database_error_handler: DATABASE_ERROR_HANDLER - -- Error handler + -- Error handler. once create Result.make end +feature -- Status Report + + has_error: BOOLEAN + -- Has error? + do + Result := database_error_handler.has_error + end + feature -- Helper exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) diff --git a/persistence/implementation/mysql/src/cms_storage_mysql.e b/persistence/implementation/mysql/src/cms_storage_mysql.e index 74a72ce..47b74ca 100644 --- a/persistence/implementation/mysql/src/cms_storage_mysql.e +++ b/persistence/implementation/mysql/src/cms_storage_mysql.e @@ -21,6 +21,7 @@ feature {NONE} -- Initialization require is_connected: a_connection.is_connected do + connection := a_connection log.write_information (generator+".make_with_database is database connected? "+ a_connection.is_connected.out ) create node_provider.make (a_connection) create user_provider.make (a_connection) @@ -125,11 +126,14 @@ feature -- Change: user save_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 + connection.begin_transaction user_provider.new_user (a_user.name, l_password, l_email) + connection.commit else set_last_error ("User or Password not attached", generator + ".save_user") end @@ -282,4 +286,6 @@ feature {NONE} -- Post process user_provider: USER_DATA_PROVIDER -- User Data provider. + connection: DATABASE_CONNECTION + -- Current database connection. end diff --git a/persistence/implementation/mysql/src/database/database_connection_mysql.e b/persistence/implementation/mysql/src/database/database_connection_mysql.e index bc5f890..b9d173f 100644 --- a/persistence/implementation/mysql/src/database/database_connection_mysql.e +++ b/persistence/implementation/mysql/src/database/database_connection_mysql.e @@ -34,17 +34,11 @@ feature -- Initialization if keep_connection then connect end - set_successful else create db_control.make end rescue - create db_control.make - set_last_error_from_exception ("Connection execution") - log.write_critical (generator + ".make_common:" + last_error_message) - if is_connected then - disconnect - end + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) l_retried := True retry end @@ -66,17 +60,11 @@ feature -- Initialization if keep_connection then connect end - set_successful else create db_control.make end rescue - create db_control.make - set_last_error_from_exception ("Connection execution") - log.write_critical (generator + ".make_common:" + last_error_message) - if is_connected then - disconnect - end + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) l_retried := True retry end diff --git a/persistence/implementation/mysql/src/provider/node_data_provider.e b/persistence/implementation/mysql/src/provider/node_data_provider.e index 3bcfc84..59c9bae 100644 --- a/persistence/implementation/mysql/src/provider/node_data_provider.e +++ b/persistence/implementation/mysql/src/provider/node_data_provider.e @@ -34,7 +34,6 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do - Result := db_handler.successful end feature -- Access @@ -481,13 +480,6 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do - if db_handler.successful then - set_successful - else - if attached db_handler.last_error then - set_last_error_from_handler (db_handler.last_error) - end - end end end diff --git a/persistence/implementation/mysql/src/provider/role_data_provider.e b/persistence/implementation/mysql/src/provider/role_data_provider.e index 61590a0..8e82a64 100644 --- a/persistence/implementation/mysql/src/provider/role_data_provider.e +++ b/persistence/implementation/mysql/src/provider/role_data_provider.e @@ -35,7 +35,7 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do - Result := db_handler.successful +-- Result := db_handler.successful end has_roles: BOOLEAN @@ -210,13 +210,7 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do - if db_handler.successful then - set_successful - else - if attached db_handler.last_error then - set_last_error_from_handler (db_handler.last_error) - end - end + end end diff --git a/persistence/implementation/mysql/src/provider/user_data_provider.e b/persistence/implementation/mysql/src/provider/user_data_provider.e index a1ac47b..0d9b0bf 100644 --- a/persistence/implementation/mysql/src/provider/user_data_provider.e +++ b/persistence/implementation/mysql/src/provider/user_data_provider.e @@ -34,7 +34,6 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do - Result := db_handler.successful end has_user: BOOLEAN @@ -311,13 +310,6 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do - if db_handler.successful then - set_successful - else - if attached db_handler.last_error then - set_last_error_from_handler (db_handler.last_error) - end - end end end diff --git a/persistence/implementation/mysql/tests/util/clean_db.e b/persistence/implementation/mysql/tests/util/clean_db.e index 965465f..dce7176 100644 --- a/persistence/implementation/mysql/tests/util/clean_db.e +++ b/persistence/implementation/mysql/tests/util/clean_db.e @@ -24,6 +24,7 @@ feature do create l_parameters.make (0) + a_connection.begin_transaction -- Clean Profiles db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Sql_delete_user_profiles, l_parameters)) @@ -72,6 +73,7 @@ feature db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Rest_profiles_autoincrement, l_parameters)) db_handler(a_connection).execute_change + a_connection.commit end From ab76a752d787f1b2f75879251a027a7fbf63f44d Mon Sep 17 00:00:00 2001 From: jvelilla Date: Mon, 13 Oct 2014 18:45:45 -0300 Subject: [PATCH 06/20] Added nested transaction support. Added test cases showing transaction support scenarios. --- .../common/database/database_connection.e | 136 ++++++++++++++ .../tests/transactions/transaction_test_set.e | 168 ++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 persistence/implementation/mysql/tests/transactions/transaction_test_set.e diff --git a/persistence/implementation/common/database/database_connection.e b/persistence/implementation/common/database/database_connection.e index cfb9fd9..a6c2d2c 100644 --- a/persistence/implementation/common/database/database_connection.e +++ b/persistence/implementation/common/database/database_connection.e @@ -131,6 +131,142 @@ feature -- Transactions retry end + +feature -- + + is_connected_to_storage: BOOLEAN + -- Is connected to the database + do + Result := db_control.is_connected + end + +feature -- Transaction Status + + in_transaction_session: BOOLEAN + -- Is session started? + + transaction_session_depth: INTEGER + -- Depth in the transaction session + +feature -- Transaction Operation + + begin_transaction2 + -- Start session + -- if already started, increase the `transaction_session_depth' + require + in_transaction_session implies transaction_session_depth > 0 + not in_transaction_session implies transaction_session_depth = 0 + local + l_session_control: like db_control + l_retried: INTEGER + do + if l_retried = 0 then + if not in_transaction_session then + database_error_handler.reset + + check transaction_session_depth = 0 end + + debug ("database_session") + print ("..Start session%N") + end + connect -- connect the DB + if is_connected_to_storage then + in_transaction_session := True + db_control.begin -- start transaction + else + l_session_control := db_control + if not l_session_control.is_ok then + database_error_handler.add_database_error (l_session_control.error_message_32, l_session_control.error_code) + else + database_error_handler.add_database_error ("Session_not_started_error_message", 0) + end + l_session_control.reset + end + end + transaction_session_depth := transaction_session_depth + 1 + else + if l_retried = 1 then + transaction_session_depth := transaction_session_depth + 1 + if attached (create {EXCEPTION_MANAGER}).last_exception as e then + if attached {ASSERTION_VIOLATION} e then + --| Ignore for now with MYSQL ... + else + exception_as_error (e) + end + end + + in_transaction_session := False + db_control.reset + else + in_transaction_session := False + end + end + ensure + transaction_session_depth = (old transaction_session_depth) + 1 + rescue + l_retried := l_retried + 1 + retry + end + + commit2 + -- End session + local + l_retried: BOOLEAN + do + if not l_retried then + transaction_session_depth := transaction_session_depth - 1 + if transaction_session_depth = 0 then + debug ("database_session") + print ("..End session%N") + end + if is_connected_to_storage then + if not database_error_handler.has_error then + db_control.commit -- Commit transaction + else + db_control.rollback -- Rollback transaction + end + end + in_transaction_session := False + end + else + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + in_transaction_session := False + transaction_session_depth := transaction_session_depth - 1 + db_control.reset + end + rescue + l_retried := True + retry + end + + + + rollback2 + -- End session + local + l_retried: BOOLEAN + do + if not l_retried then + transaction_session_depth := transaction_session_depth - 1 + if transaction_session_depth = 0 then + debug ("database_session") + print ("..End session%N") + end + if is_connected_to_storage then + db_control.rollback -- Rollback transaction + end + in_transaction_session := False + end + else + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + in_transaction_session := False + transaction_session_depth := transaction_session_depth - 1 + db_control.reset + end + rescue + l_retried := True + retry + end feature -- Change Element not_keep_connection diff --git a/persistence/implementation/mysql/tests/transactions/transaction_test_set.e b/persistence/implementation/mysql/tests/transactions/transaction_test_set.e new file mode 100644 index 0000000..3199f71 --- /dev/null +++ b/persistence/implementation/mysql/tests/transactions/transaction_test_set.e @@ -0,0 +1,168 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + TRANSACTION_TEST_SET + +inherit + + EQA_TEST_SET + redefine + on_prepare, + on_clean + select + default_create + end + ABSTRACT_DB_TEST + rename + default_create as default_db_test + end + + +feature {NONE} -- Events + + on_prepare + -- + do + (create {CLEAN_DB}).clean_db(connection) + end + + on_clean + -- + do + end + +feature -- Test routines + + test_user_rollback + note + testing: "execution/isolated" + do + connection.begin_transaction + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + connection.rollback + assert ("Not has user:", not user_provider.has_user) + end + + test_user_node_rollback + note + testing: "execution/isolated" + do + connection.begin_transaction + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + node_provider.add_author (1, 1) + assert ("Has one node:", node_provider.count = 1) + connection.rollback + assert ("Not has user:", not user_provider.has_user) + assert ("Not has nodes:", node_provider.count = 0) + end + + + + test_user_node_nested_transaction_with_rollback_not_supported + note + testing: "execution/isolated" + do + connection.begin_transaction2 + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + assert ("Has one node:", node_provider.count = 1) + + connection.begin_transaction2 + user_provider.new_user ("test1", "test1","test1@admin.com") + assert ("Has user: test1", attached user_provider.user_by_name ("test1")) + connection.rollback2 + + connection.commit2 + assert ("Has user test:", attached user_provider.user_by_name ("test")) + assert ("Has nodes:", node_provider.count = 1) + assert ("Not has user: test1", user_provider.user_by_name ("test1") = Void) + end + + + test_user_node_nested_transaction_with_commit + note + testing: "execution/isolated" + do + connection.begin_transaction2 + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + assert ("Has one node:", node_provider.count = 1) + + connection.begin_transaction2 + user_provider.new_user ("test1", "test1","test1@admin.com") + assert ("Has user: test1", attached user_provider.user_by_name ("test1")) + connection.commit2 + + connection.commit2 + assert ("Has user test:", attached user_provider.user_by_name ("test")) + assert ("Has user test1:", attached user_provider.user_by_name ("test1")) + assert ("Has nodes:", node_provider.count = 1) + end + + + test_user_node_nested_transaction_with_rollback + note + testing: "execution/isolated" + do + connection.begin_transaction2 + user_provider.new_user ("test", "test","test@admin.com") + assert ("Has user:", user_provider.has_user) + node_provider.new_node (default_node) + assert ("Has one node:", node_provider.count = 1) + + connection.begin_transaction2 + user_provider.new_user ("test1", "test1","test1@admin.com") + assert ("Has user: test1", attached user_provider.user_by_name ("test1")) + connection.commit2 + + connection.rollback2 + assert ("Not Has user test:", user_provider.user_by_name ("test") = void) + assert ("Not Has user test1:", user_provider.user_by_name ("test1") = void) + assert ("Has 0 nodes:", node_provider.count = 0) + end + + + + + +feature {NONE} -- Implementation + + node_provider: NODE_DATA_PROVIDER + -- node provider. + once + create Result.make (connection) + end + + user_provider: USER_DATA_PROVIDER + -- user provider. + once + create Result.make (connection) + end + + +feature {NONE} -- Implementation Fixture Factories + + default_node: CMS_NODE + do + Result := custom_node ("Default content", "default summary", "Default") + end + + custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_NODE + do + create Result.make (a_content, a_summary, a_title) + end +end + + From 3c73202a0de7037152f5bae7d8fe6051a99480b5 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 15 Oct 2014 19:41:47 -0300 Subject: [PATCH 07/20] Initial Import Model Library --- cms/cms-safe.ecf | 2 + model/model-safe.ecf | 19 +++ model/src/cms_content_type.e | 10 ++ model/src/cms_link.e | 71 ++++++++++++ model/src/cms_link_composite.e | 27 +++++ model/src/cms_local_link.e | 109 ++++++++++++++++++ model/src/cms_menu.e | 72 ++++++++++++ .../common/model => model/src}/cms_node.e | 0 .../common/model => model/src}/cms_user.e | 0 .../model => model/src}/cms_user_profile.e | 0 .../model => model/src}/cms_user_role.e | 0 .../database/error/shared_error_handler.e | 2 +- .../mysql/persistence_mysql-safe.ecf | 1 + 13 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 model/model-safe.ecf create mode 100644 model/src/cms_content_type.e create mode 100644 model/src/cms_link.e create mode 100644 model/src/cms_link_composite.e create mode 100644 model/src/cms_local_link.e create mode 100644 model/src/cms_menu.e rename {persistence/implementation/common/model => model/src}/cms_node.e (100%) rename {persistence/implementation/common/model => model/src}/cms_user.e (100%) rename {persistence/implementation/common/model => model/src}/cms_user_profile.e (100%) rename {persistence/implementation/common/model => model/src}/cms_user_role.e (100%) diff --git a/cms/cms-safe.ecf b/cms/cms-safe.ecf index 5da317c..3a5945e 100644 --- a/cms/cms-safe.ecf +++ b/cms/cms-safe.ecf @@ -10,6 +10,8 @@ + + diff --git a/model/model-safe.ecf b/model/model-safe.ecf new file mode 100644 index 0000000..cc50b08 --- /dev/null +++ b/model/model-safe.ecf @@ -0,0 +1,19 @@ + + + + + + + + + + + /EIFGENs$ + /.svn$ + /CVS$ + + + + diff --git a/model/src/cms_content_type.e b/model/src/cms_content_type.e new file mode 100644 index 0000000..fc6cec2 --- /dev/null +++ b/model/src/cms_content_type.e @@ -0,0 +1,10 @@ +note + description: "Summary description for {CMS_CONTENT_TYPE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CMS_CONTENT_TYPE + +end diff --git a/model/src/cms_link.e b/model/src/cms_link.e new file mode 100644 index 0000000..7606366 --- /dev/null +++ b/model/src/cms_link.e @@ -0,0 +1,71 @@ +note + description: "Summary description for {CMS_MENU}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_LINK + +inherit + REFACTORING_HELPER + + DEBUG_OUTPUT + + ITERABLE [CMS_LINK] + +feature -- Access + + title: READABLE_STRING_32 + -- link's title. + + location: READABLE_STRING_8 + -- link's location. + +feature -- status report + + is_active: BOOLEAN + deferred + end + + is_expanded: BOOLEAN + deferred + end + + is_expandable: BOOLEAN + deferred + end + + has_children: BOOLEAN + deferred + end + +feature -- Query + + parent: detachable CMS_LINK + + children: detachable LIST [CMS_LINK] + deferred + end + +feature -- Access + + new_cursor: ITERATION_CURSOR [CMS_LINK] + -- Fresh cursor associated with current structure + do + if attached children as lst then + Result := lst.new_cursor + else + Result := (create {ARRAYED_LIST [CMS_LINK]}.make (0)).new_cursor + end + end + +feature -- Status report + + debug_output: STRING + -- String that should be displayed in debugger to represent `Current'. + do + Result := title.as_string_8 + " -> " + location + end + +end diff --git a/model/src/cms_link_composite.e b/model/src/cms_link_composite.e new file mode 100644 index 0000000..3a9c7da --- /dev/null +++ b/model/src/cms_link_composite.e @@ -0,0 +1,27 @@ +note + description: "Summary description for {CMS_LINK_COMPOSITE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_LINK_COMPOSITE + +inherit + ITERABLE [CMS_LINK] + +feature -- Access + + items: detachable LIST [CMS_LINK] + deferred + end + + extend (lnk: CMS_LINK) + deferred + end + + remove (lnk: CMS_LINK) + deferred + end + +end diff --git a/model/src/cms_local_link.e b/model/src/cms_local_link.e new file mode 100644 index 0000000..9633fc0 --- /dev/null +++ b/model/src/cms_local_link.e @@ -0,0 +1,109 @@ +note + description: "Summary description for {CMS_LOCAL_MENU}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_LOCAL_LINK + +inherit + CMS_LINK + + CMS_LINK_COMPOSITE + rename + items as children, + extend as add_link, + remove as remove_link + end + +create + make + +feature {NONE} -- Initialization + + make (a_title: detachable like title; a_location: like location) + do + if a_title /= Void then + title := a_title + else + title := a_location + end + location := a_location + end + +feature -- Status report + + is_active: BOOLEAN + + is_expanded: BOOLEAN + do + Result := is_expandable and then internal_is_expanded + end + + is_expandable: BOOLEAN + do + Result := internal_is_expandable or internal_is_expanded or has_children + end + + has_children: BOOLEAN + do + Result := attached children as l_children and then not l_children.is_empty + end + + permission_arguments: detachable ITERABLE [READABLE_STRING_8] + + children: detachable LIST [CMS_LINK] + + internal_is_expandable: BOOLEAN + + internal_is_expanded: BOOLEAN + +feature -- Element change + + add_link (lnk: CMS_LINK) + local + lst: like children + do + lst := children + if lst = Void then + create {ARRAYED_LIST [CMS_LINK]} lst.make (1) + children := lst + end + lst.force (lnk) + end + + remove_link (lnk: CMS_LINK) + local + lst: like children + do + lst := children + if lst /= Void then + lst.prune_all (lnk) + if lst.is_empty then + children := Void + end + end + end + + set_children (lst: like children) + do + children := lst + end + + set_expanded (b: like is_expanded) + do + internal_is_expanded := b + end + + set_expandable (b: like is_expandable) + do + internal_is_expandable := b + end + + + set_permission_arguments (args: like permission_arguments) + do + permission_arguments := args + end + +end diff --git a/model/src/cms_menu.e b/model/src/cms_menu.e new file mode 100644 index 0000000..6cb332f --- /dev/null +++ b/model/src/cms_menu.e @@ -0,0 +1,72 @@ +note + description: "Summary description for {CMS_MENU}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_MENU + +inherit + CMS_LINK_COMPOSITE + +create + make, + make_with_title + +feature {NONE} -- Initialization + + make (a_name: like name; n: INTEGER) + do + name := a_name + create items.make (n) + end + + make_with_title (a_name: like name; a_title: READABLE_STRING_32; n: INTEGER) + do + make (a_name, n) + set_title (a_title) + end + +feature -- Access + + name: READABLE_STRING_8 + + title: detachable READABLE_STRING_32 + + items: ARRAYED_LIST [CMS_LINK] + + extend (lnk: CMS_LINK) + do + items.extend (lnk) + end + + remove (lnk: CMS_LINK) + do + items.prune_all (lnk) + end + +feature -- status report + + is_empty: BOOLEAN + do + Result := items.is_empty + end + +feature -- Element change + + set_title (t: like title) + do + title := t + end + +feature -- Access + + new_cursor: ITERATION_CURSOR [CMS_LINK] + -- Fresh cursor associated with current structure + do + Result := items.new_cursor + end + +invariant + +end diff --git a/persistence/implementation/common/model/cms_node.e b/model/src/cms_node.e similarity index 100% rename from persistence/implementation/common/model/cms_node.e rename to model/src/cms_node.e diff --git a/persistence/implementation/common/model/cms_user.e b/model/src/cms_user.e similarity index 100% rename from persistence/implementation/common/model/cms_user.e rename to model/src/cms_user.e diff --git a/persistence/implementation/common/model/cms_user_profile.e b/model/src/cms_user_profile.e similarity index 100% rename from persistence/implementation/common/model/cms_user_profile.e rename to model/src/cms_user_profile.e diff --git a/persistence/implementation/common/model/cms_user_role.e b/model/src/cms_user_role.e similarity index 100% rename from persistence/implementation/common/model/cms_user_role.e rename to model/src/cms_user_role.e diff --git a/persistence/implementation/common/database/error/shared_error_handler.e b/persistence/implementation/common/database/error/shared_error_handler.e index 15c06c1..f5a80ca 100644 --- a/persistence/implementation/common/database/error/shared_error_handler.e +++ b/persistence/implementation/common/database/error/shared_error_handler.e @@ -31,7 +31,7 @@ feature -- Helper exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) -- Record exception as an error. do - if attached a_e as l_e and then attached l_e.exception_trace as l_trace then + if attached a_e as l_e and then attached l_e.trace as l_trace then database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32) end end diff --git a/persistence/implementation/mysql/persistence_mysql-safe.ecf b/persistence/implementation/mysql/persistence_mysql-safe.ecf index 6811629..9d99a01 100644 --- a/persistence/implementation/mysql/persistence_mysql-safe.ecf +++ b/persistence/implementation/mysql/persistence_mysql-safe.ecf @@ -13,6 +13,7 @@ + From 5cb26f0b24fdee9ff5d38b4fbe55632fce6d226a Mon Sep 17 00:00:00 2001 From: jvelilla Date: Fri, 17 Oct 2014 08:53:02 -0300 Subject: [PATCH 08/20] Updated Peristance layer to use the new error_hanler based on EWF error library. Remove once use from DATABASE_ERROR_HANDLER. Initial support transaction handling. --- .../implementation/common/cms_storage_null.e | 14 + .../common/database/database_connection.e | 162 ++------ .../database/database_connection_null.e | 1 + .../common/database/database_handler.e | 29 +- .../common/database/database_handler_impl.e | 7 +- .../common/database/database_query.e | 4 +- .../database/database_storage_manager.e | 371 ------------------ .../{ => error}/database_no_change_error.e | 0 .../database/error/shared_error_handler.e | 39 -- .../mysql/src/cms_storage_mysql.e | 54 +-- .../src/database/database_connection_mysql.e | 9 +- .../mysql/src/provider/node_data_provider.e | 38 +- .../mysql/src/provider/user_data_provider.e | 26 +- .../tests/handler/database_handler_test.e | 81 ++++ .../mysql/tests/nodes/node_test_set.e | 14 +- .../implementation/mysql/tests/tests.ecf | 1 + .../tests/transactions/transaction_test_set.e | 71 ---- persistence/interface/cms_storage.e | 7 +- 18 files changed, 254 insertions(+), 674 deletions(-) delete mode 100644 persistence/implementation/common/database/database_storage_manager.e rename persistence/implementation/common/database/{ => error}/database_no_change_error.e (100%) delete mode 100644 persistence/implementation/common/database/error/shared_error_handler.e create mode 100644 persistence/implementation/mysql/tests/handler/database_handler_test.e diff --git a/persistence/implementation/common/cms_storage_null.e b/persistence/implementation/common/cms_storage_null.e index c82e9b6..89eb3df 100644 --- a/persistence/implementation/common/cms_storage_null.e +++ b/persistence/implementation/common/cms_storage_null.e @@ -9,8 +9,22 @@ class inherit CMS_STORAGE + redefine + default_create + select + default_create + end REFACTORING_HELPER + rename + default_create as default_create_rh + end +feature -- Initialization + + default_create + do + create error_handler.make + end feature -- Access: user diff --git a/persistence/implementation/common/database/database_connection.e b/persistence/implementation/common/database/database_connection.e index a6c2d2c..5f0e9f7 100644 --- a/persistence/implementation/common/database/database_connection.e +++ b/persistence/implementation/common/database/database_connection.e @@ -10,8 +10,6 @@ inherit DATABASE_CONFIG - SHARED_ERROR_HANDLER - feature {NONE} -- Initialization make_common @@ -131,142 +129,6 @@ feature -- Transactions retry end - -feature -- - - is_connected_to_storage: BOOLEAN - -- Is connected to the database - do - Result := db_control.is_connected - end - -feature -- Transaction Status - - in_transaction_session: BOOLEAN - -- Is session started? - - transaction_session_depth: INTEGER - -- Depth in the transaction session - -feature -- Transaction Operation - - begin_transaction2 - -- Start session - -- if already started, increase the `transaction_session_depth' - require - in_transaction_session implies transaction_session_depth > 0 - not in_transaction_session implies transaction_session_depth = 0 - local - l_session_control: like db_control - l_retried: INTEGER - do - if l_retried = 0 then - if not in_transaction_session then - database_error_handler.reset - - check transaction_session_depth = 0 end - - debug ("database_session") - print ("..Start session%N") - end - connect -- connect the DB - if is_connected_to_storage then - in_transaction_session := True - db_control.begin -- start transaction - else - l_session_control := db_control - if not l_session_control.is_ok then - database_error_handler.add_database_error (l_session_control.error_message_32, l_session_control.error_code) - else - database_error_handler.add_database_error ("Session_not_started_error_message", 0) - end - l_session_control.reset - end - end - transaction_session_depth := transaction_session_depth + 1 - else - if l_retried = 1 then - transaction_session_depth := transaction_session_depth + 1 - if attached (create {EXCEPTION_MANAGER}).last_exception as e then - if attached {ASSERTION_VIOLATION} e then - --| Ignore for now with MYSQL ... - else - exception_as_error (e) - end - end - - in_transaction_session := False - db_control.reset - else - in_transaction_session := False - end - end - ensure - transaction_session_depth = (old transaction_session_depth) + 1 - rescue - l_retried := l_retried + 1 - retry - end - - commit2 - -- End session - local - l_retried: BOOLEAN - do - if not l_retried then - transaction_session_depth := transaction_session_depth - 1 - if transaction_session_depth = 0 then - debug ("database_session") - print ("..End session%N") - end - if is_connected_to_storage then - if not database_error_handler.has_error then - db_control.commit -- Commit transaction - else - db_control.rollback -- Rollback transaction - end - end - in_transaction_session := False - end - else - exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) - in_transaction_session := False - transaction_session_depth := transaction_session_depth - 1 - db_control.reset - end - rescue - l_retried := True - retry - end - - - - rollback2 - -- End session - local - l_retried: BOOLEAN - do - if not l_retried then - transaction_session_depth := transaction_session_depth - 1 - if transaction_session_depth = 0 then - debug ("database_session") - print ("..End session%N") - end - if is_connected_to_storage then - db_control.rollback -- Rollback transaction - end - in_transaction_session := False - end - else - exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) - in_transaction_session := False - transaction_session_depth := transaction_session_depth - 1 - db_control.reset - end - rescue - l_retried := True - retry - end feature -- Change Element not_keep_connection @@ -302,4 +164,28 @@ feature -- Conection Result := db_control.is_connected end +feature -- Error Handling + + database_error_handler: DATABASE_ERROR_HANDLER + -- Error handler. + +feature -- Status Report + + has_error: BOOLEAN + -- Has error? + do + Result := database_error_handler.has_error + end + +feature -- Helper + + exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) + -- Record exception as an error. + do + if attached a_e as l_e and then attached l_e.trace as l_trace then + database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32) + end + end + + end diff --git a/persistence/implementation/common/database/database_connection_null.e b/persistence/implementation/common/database/database_connection_null.e index d9257b3..ec54d13 100644 --- a/persistence/implementation/common/database/database_connection_null.e +++ b/persistence/implementation/common/database/database_connection_null.e @@ -22,6 +22,7 @@ feature -- Initialization make_common -- Create a database handler for ODBC with common settings. do + create database_error_handler.make create db_application.login (username, password) db_application.set_hostname (hostname) db_application.set_data_source (database_name) diff --git a/persistence/implementation/common/database/database_handler.e b/persistence/implementation/common/database/database_handler.e index 875b7a7..3517ff3 100644 --- a/persistence/implementation/common/database/database_handler.e +++ b/persistence/implementation/common/database/database_handler.e @@ -8,7 +8,7 @@ deferred class inherit - SHARED_ERROR_HANDLER + SHARED_LOGGER feature -- Access @@ -178,6 +178,7 @@ feature -- Error handling if attached db_change as l_change and then not l_change.is_ok then database_error_handler.add_database_error (l_change.error_message_32, l_change.error_code) log.write_error (generator + ".check_database_change_error: " + l_change.error_message_32) + l_change.reset end end @@ -187,10 +188,34 @@ feature -- Error handling if attached db_selection as l_selection and then not l_selection.is_ok then database_error_handler.add_database_error (l_selection.error_message_32, l_selection.error_code) log.write_error (generator + ".check_database_selection_error: " + l_selection.error_message_32) + l_selection.reset end end -feature {NODE_DATA_PROVIDER}-- Implementation +feature -- Error Handling + + database_error_handler: DATABASE_ERROR_HANDLER + -- Error handler. + +feature -- Status Report + + has_error: BOOLEAN + -- Has error? + do + Result := database_error_handler.has_error + end + +feature -- Helper + + exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) + -- Record exception as an error. + do + if attached a_e as l_e and then attached l_e.trace as l_trace then + database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32) + end + end + +feature -- Connection Handling connect -- Connect to the database. diff --git a/persistence/implementation/common/database/database_handler_impl.e b/persistence/implementation/common/database/database_handler_impl.e index 55bde06..1de28a1 100644 --- a/persistence/implementation/common/database/database_handler_impl.e +++ b/persistence/implementation/common/database/database_handler_impl.e @@ -21,9 +21,11 @@ feature {NONE} -- Initialization do connection := a_connection create last_query.make_now + create database_error_handler.make ensure connection_not_void: connection /= Void last_query_not_void: last_query /= Void + database_error_handler_set: attached database_error_handler end feature -- Functionality @@ -35,6 +37,7 @@ feature -- Functionality l_retried: BOOLEAN do if not l_retried then + database_error_handler.reset if attached store as l_store then create l_db_selection.make db_selection := l_db_selection @@ -59,7 +62,7 @@ feature -- Functionality l_retried : BOOLEAN do if not l_retried then - + database_error_handler.reset if attached store as l_store then create l_db_change.make db_change := l_db_change @@ -86,6 +89,7 @@ feature -- SQL Queries l_retried: BOOLEAN do if not l_retried then + database_error_handler.reset if attached query as l_query then create l_db_selection.make db_selection := l_db_selection @@ -110,6 +114,7 @@ feature -- SQL Queries l_retried : BOOLEAN do if not l_retried then + database_error_handler.reset if attached query as l_query then create l_db_change.make db_change := l_db_change diff --git a/persistence/implementation/common/database/database_query.e b/persistence/implementation/common/database/database_query.e index 4acec0c..25088b3 100644 --- a/persistence/implementation/common/database/database_query.e +++ b/persistence/implementation/common/database/database_query.e @@ -8,10 +8,10 @@ class inherit - SHARED_ERROR_HANDLER - REFACTORING_HELPER + SHARED_LOGGER + create data_reader diff --git a/persistence/implementation/common/database/database_storage_manager.e b/persistence/implementation/common/database/database_storage_manager.e deleted file mode 100644 index e59ef5a..0000000 --- a/persistence/implementation/common/database/database_storage_manager.e +++ /dev/null @@ -1,371 +0,0 @@ -note - description: "[ - Manager to initialize data api for database access, - create database connection and so on - ]" - date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" - revision: "$Revision: 195 $" - -class - DATABASE_STORAGE_MANAGER - -inherit - GLOBAL_SETTINGS - - REFACTORING_HELPER - - SHARED_ERROR_HANDLER - -create - make - -feature -- Initialization - - make (a_data_app: like data_app; a_database_name: like database_name; a_name: like name; a_password: like password; - a_host_name: like host_name; a_role_id: like role_id; a_role_password: like role_password - a_data_source: like data_source; a_group: like group) - -- Initialize with login info. - -- - -- `a_database_name' is used for MySQL - -- `a_name', the login user name - -- `a_password', the login user password, unencrypted. - local - l_storage: STRING_8 - do - create l_storage.make (64) - storage_url := l_storage - l_storage.append (a_data_app.db_spec.database_handle_name.as_lower) - l_storage.append ("://") - - data_app := a_data_app - database_name := a_database_name - name := a_name - password := a_password - host_name := a_host_name - role_id := a_role_id - role_password := a_role_password - data_source := a_data_source - group := a_group - - set_use_extended_types (True) - set_map_zero_null_value (False) - - l_storage.append (a_name.as_string_8) - l_storage.append (":********@") - if a_host_name /= Void then - a_data_app.set_hostname (a_host_name) - l_storage.append (a_host_name) - end - - if a_database_name /= Void then - a_data_app.set_application (a_database_name.as_string_8) - l_storage.append ("/" + a_database_name.as_string_8) - end - - if a_data_source /= Void then - a_data_app.set_data_source (a_data_source) - end - if a_role_id /= Void and then a_role_password /= Void then - a_data_app.set_role (a_role_id, a_role_password) - end - if a_group /= Void then - a_data_app.set_group (a_group) - end - - a_data_app.login (a_name.as_string_8, a_password.as_string_8) - a_data_app.set_base - - create session_control.make - - end - - report_database_schema_incompatibility (a_output: BOOLEAN) - -- Report the application code is not compatible with database schema version - -- if `a_output' is True, write error in io.error as well - require --- incompatible_database_schema_version: not is_database_schema_version_compatible - local - db_v: READABLE_STRING_8 - do --- if attached database_schema_version as v then --- db_v := v.version --- else --- db_v := "?.?.?.?" --- end --- database_error_handler.add_error_details (0, "MISC Error", "Schema version incompatible (application=" --- + database_storage_version.version + " database=" + db_v + ")." --- ) - if a_output then - io.error.put_string (database_error_handler.as_string_representation) - io.error.put_new_line - end - end - -feature -- System Update - - update_system - do --- if is_database_schema_version_compatible then --- misc_manager.initialize_reference_types --- history_manager.initialize_data --- user_role_permission_manager.initialize_built_in_user_role_permission --- user_role_permission_manager.initialize_extra_user_role_permission --- task_manager.initialize_data --- else --- -- If schema incompatible, report it and exit --- report_database_schema_incompatibility (True) --- (create {EXCEPTIONS}).die (-1) --- end - --- [2012-Mars-21] Idea about update system implementation --- if update_version < 01.00.0012 then --- if update_version < 01.00.0005 then --- update_version_01_00_0005 --- end --- update_version_01_00_0012 --- end - end - - reset_storage_manager - do --- initialize_managers (Current) - end - -feature -- Storage - - storage_url: READABLE_STRING_8 - -- Associated storage URL - - storage_connection_kept_alive: BOOLEAN - -- Keep storage connection alive? - -- i.e: never disconnect between 2 transactions. - - keep_storage_connection_alive (b: BOOLEAN) - do - storage_connection_kept_alive := b - end - - connect_storage - -- Connect the database - do - if not session_control.is_connected then - session_control.connect - end - end - - disconnect_from_storage - -- Disconnect from the storage - require - is_connected_to_storage: is_connected_to_storage - do - if not storage_connection_kept_alive then - session_control.disconnect - end - end - - force_disconnect_from_storage - -- Force disconnection from the storage - -- i.e ignore any `storage_connection_kept_alive' - do - if session_control.is_connected then - session_control.disconnect - end - end - - is_connected_to_storage: BOOLEAN - -- Is connected to the database - do - Result := session_control.is_connected - end - -feature -- Transaction Status - - in_transaction_session: BOOLEAN - -- Is session started? - - transaction_session_depth: INTEGER - -- Depth in the transaction session - -feature -- Transaction Operation - - start_transaction_session - -- Start session - -- if already started, increase the `transaction_session_depth' - require - in_transaction_session implies transaction_session_depth > 0 - not in_transaction_session implies transaction_session_depth = 0 - local - l_session_control: like session_control - l_retried: INTEGER - do - if l_retried = 0 then - if not in_transaction_session then - database_error_handler.reset - - check transaction_session_depth = 0 end - - debug ("database_session") - print ("..Start session%N") - end - connect_storage -- connect the DB - if is_connected_to_storage then - in_transaction_session := True - session_control.begin -- start transaction - else - l_session_control := session_control - if not l_session_control.is_ok then - database_error_handler.add_database_error (l_session_control.error_message_32, l_session_control.error_code) - else - database_error_handler.add_database_error (Session_not_started_error_message, 0) - end - l_session_control.reset - end - end - transaction_session_depth := transaction_session_depth + 1 - else - if l_retried = 1 then - transaction_session_depth := transaction_session_depth + 1 - if attached (create {EXCEPTION_MANAGER}).last_exception as e then - if attached {ASSERTION_VIOLATION} e then - --| Ignore for now with MYSQL ... - else - exception_as_error (e) - end - end - - in_transaction_session := False - session_control.reset - else - in_transaction_session := False - end - end - ensure - transaction_session_depth = (old transaction_session_depth) + 1 - rescue - l_retried := l_retried + 1 - retry - end - - end_transaction_session - -- End session - local - l_retried: BOOLEAN - do - if not l_retried then - transaction_session_depth := transaction_session_depth - 1 - if transaction_session_depth = 0 then - debug ("database_session") - print ("..End session%N") - end - if is_connected_to_storage then - if not database_error_handler.has_error then - session_control.commit -- Commit transaction - else - session_control.rollback -- Rollback transaction - end - disconnect_from_storage - end - in_transaction_session := False - end - else - exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) - in_transaction_session := False - transaction_session_depth := transaction_session_depth - 1 - session_control.reset - end - rescue - l_retried := True - retry - end - - execute_query (a_query: STRING_32) - -- Execute `a_q' - require - is_session_started: in_transaction_session - local - rescued: BOOLEAN - l_change: like new_database_change - do - if not rescued then - session_control.reset - l_change := new_database_change - l_change.set_query (a_query) - l_change.execute_query - else - database_error_handler.add_error_details (0, "Unexpected Error", "Unexpected Error when executing query") - end - rescue - rescued := True - retry - end - -feature -- Element Change - - set_last_inserted_id_function (a_f: like last_inserted_id_function) - -- Set `last_inserted_id_function' with `a_f' - do - last_inserted_id_function := a_f - ensure - last_inserted_id_function_set: last_inserted_id_function = a_f - end - -feature -- Access - - database_name: detachable READABLE_STRING_GENERAL - -- Database to access - - name: READABLE_STRING_GENERAL - -- Login user name - - password: READABLE_STRING_8 - -- Password - - host_name: detachable READABLE_STRING_8 - -- Host name, and port if needed - - role_id: detachable READABLE_STRING_8 - -- Role id - - role_password: detachable READABLE_STRING_8 - -- Role password - - data_source: detachable READABLE_STRING_8 - -- Data source - - group: detachable READABLE_STRING_8 - -- Group - - data_app: DATABASE_APPL [DATABASE] - -- Database application - - last_inserted_id_function: detachable FUNCTION [ANY, TUPLE, NATURAL_64] - -- Function to get last inserted id. - -feature -- Factory - - new_database_change: DB_CHANGE - -- Database change - do - create Result.make - end - - new_database_selection: DB_SELECTION - -- Database selection - do - create Result.make - end - - new_procedure (a_name: like {DB_PROC}.name): DB_PROC - -- Database procedure - do - create Result.make (a_name) - end - -feature {NONE} -- Implementation - - session_not_started_error_message: STRING_32 = "Session could not be started for unknown reason" - - session_control: DB_CONTROL - -- Session - -end diff --git a/persistence/implementation/common/database/database_no_change_error.e b/persistence/implementation/common/database/error/database_no_change_error.e similarity index 100% rename from persistence/implementation/common/database/database_no_change_error.e rename to persistence/implementation/common/database/error/database_no_change_error.e diff --git a/persistence/implementation/common/database/error/shared_error_handler.e b/persistence/implementation/common/database/error/shared_error_handler.e deleted file mode 100644 index f5a80ca..0000000 --- a/persistence/implementation/common/database/error/shared_error_handler.e +++ /dev/null @@ -1,39 +0,0 @@ -note - description: "Shared error handler for database" - date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" - revision: "$Revision: 195 $" - -class - SHARED_ERROR_HANDLER - -inherit - - SHARED_LOGGER - -feature -- Access - - database_error_handler: DATABASE_ERROR_HANDLER - -- Error handler. - once - create Result.make - end - -feature -- Status Report - - has_error: BOOLEAN - -- Has error? - do - Result := database_error_handler.has_error - end - -feature -- Helper - - exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) - -- Record exception as an error. - do - if attached a_e as l_e and then attached l_e.trace as l_trace then - database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32) - end - end - -end diff --git a/persistence/implementation/mysql/src/cms_storage_mysql.e b/persistence/implementation/mysql/src/cms_storage_mysql.e index 47b74ca..62422aa 100644 --- a/persistence/implementation/mysql/src/cms_storage_mysql.e +++ b/persistence/implementation/mysql/src/cms_storage_mysql.e @@ -25,8 +25,7 @@ feature {NONE} -- Initialization log.write_information (generator+".make_with_database is database connected? "+ a_connection.is_connected.out ) create node_provider.make (a_connection) create user_provider.make (a_connection) - post_node_provider_execution - post_user_provider_execution + create error_handler.make end @@ -36,7 +35,6 @@ feature -- Access: user -- Has any user? do Result := user_provider.has_user - post_user_provider_execution end all_users: LIST [CMS_USER] @@ -48,19 +46,19 @@ feature -- Access: user user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER do Result := user_provider.user (a_id) - post_user_provider_execution + end user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER do Result := user_provider.user_by_name (a_name) - post_user_provider_execution + end user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER do Result := user_provider.user_by_email (a_email) - post_user_provider_execution + end is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN @@ -82,7 +80,7 @@ feature -- Access: user log.write_information (generator + ".login_valid User:" + l_auth_login + "does not exist" ) end end - post_user_provider_execution + end feature -- User Nodes @@ -135,7 +133,6 @@ feature -- Change: user user_provider.new_user (a_user.name, l_password, l_email) connection.commit else - set_last_error ("User or Password not attached", generator + ".save_user") end end @@ -148,7 +145,7 @@ feature -- Access: node across node_provider.nodes as c loop Result.force (c.item) end - post_node_provider_execution + end recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE] @@ -158,21 +155,21 @@ feature -- Access: node across node_provider.recent_nodes (a_lower,a_count) as c loop Result.force (c.item) end - post_node_provider_execution + end node (a_id: INTEGER_64): detachable CMS_NODE -- do Result := node_provider.node (a_id) - post_node_provider_execution + end node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER -- do Result := node_provider.node_author (a_id) - post_node_provider_execution + end node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER] @@ -188,21 +185,21 @@ feature -- Node -- do node_provider.new_node (a_node) - post_node_provider_execution + end delete_node (a_id: INTEGER_64) do node_provider.delete_from_user_nodes(a_id) node_provider.delete_node (a_id) - post_node_provider_execution + end update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE) -- do node_provider.update_node (a_id, a_node) - post_node_provider_execution + end update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32) @@ -210,7 +207,7 @@ feature -- Node do node_provider.update_node_title (a_node_id, a_title) internal_node_update (a_id, a_node_id) - post_node_provider_execution + end update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32) @@ -218,7 +215,7 @@ feature -- Node do node_provider.update_node_summary (a_node_id, a_summary) internal_node_update (a_id, a_node_id) - post_node_provider_execution + end update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32) @@ -226,7 +223,7 @@ feature -- Node do node_provider.update_node_content (a_node_id, a_content) internal_node_update (a_id, a_node_id) - post_node_provider_execution + end feature {NONE} -- NODE Implemenation @@ -258,27 +255,6 @@ feature -- User feature {NONE} -- Post process - post_node_provider_execution - do - if node_provider.successful then - set_successful - else - if attached node_provider.last_error then - set_last_error_from_handler (node_provider.last_error) - end - end - end - - post_user_provider_execution - do - if user_provider.successful then - set_successful - else - if attached user_provider.last_error then - set_last_error_from_handler (user_provider.last_error) - end - end - end node_provider: NODE_DATA_PROVIDER -- Node Data provider. diff --git a/persistence/implementation/mysql/src/database/database_connection_mysql.e b/persistence/implementation/mysql/src/database/database_connection_mysql.e index b9d173f..05776f6 100644 --- a/persistence/implementation/mysql/src/database/database_connection_mysql.e +++ b/persistence/implementation/mysql/src/database/database_connection_mysql.e @@ -23,6 +23,7 @@ feature -- Initialization local l_retried: BOOLEAN do + create database_error_handler.make create db_application.login (username, password) if not l_retried then @@ -38,6 +39,7 @@ feature -- Initialization create db_control.make end rescue + create database_error_handler.make exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) l_retried := True retry @@ -49,6 +51,7 @@ feature -- Initialization local l_retried: BOOLEAN do + create database_error_handler.make create db_application.login (username, password) if not l_retried then @@ -64,6 +67,7 @@ feature -- Initialization create db_control.make end rescue + create database_error_handler.make exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) l_retried := True retry @@ -76,6 +80,7 @@ feature -- Initialization -- `database_name' to `a_database_name' -- `connection' to `a_connection' do + create database_error_handler.make create db_application.login (a_username, a_password) db_application.set_hostname (a_hostname) db_application.set_data_source (a_database_name) @@ -97,6 +102,8 @@ feature -- Initialization l_user: STRING l_password: STRING do + create database_error_handler.make + l_string := a_string.split (';') l_server := l_string.at (2).split ('=').at (2) l_port := l_string.at (3).split ('=').at (2) @@ -111,12 +118,12 @@ feature -- Initialization db_application.set_base create db_control.make keep_connection := is_keep_connection - end login_with_schema (a_schema: STRING; a_username: STRING; a_password: STRING) -- Login with `a_connection_string'and immediately connect to database. do + create database_error_handler.make create db_application db_application.set_application (a_schema) db_application.login_and_connect (a_username, a_password) diff --git a/persistence/implementation/mysql/src/provider/node_data_provider.e b/persistence/implementation/mysql/src/provider/node_data_provider.e index 59c9bae..5951cc5 100644 --- a/persistence/implementation/mysql/src/provider/node_data_provider.e +++ b/persistence/implementation/mysql/src/provider/node_data_provider.e @@ -10,10 +10,10 @@ inherit PARAMETER_NAME_HELPER - SHARED_ERROR - REFACTORING_HELPER + SHARED_LOGGER + create make @@ -23,6 +23,7 @@ feature -- Initialization -- Create a data provider. do create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection) + create error_handler.make post_execution end @@ -34,8 +35,13 @@ feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do + Result := not error_handler.has_error end +feature -- Error Handler + + error_handler: ERROR_HANDLER + feature -- Access nodes: DATABASE_ITERATION_CURSOR [CMS_NODE] @@ -43,6 +49,7 @@ feature -- Access local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".nodes") create l_parameters.make (0) db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_nodes, l_parameters)) @@ -57,6 +64,7 @@ feature -- Access l_parameters: STRING_TABLE [ANY] l_query: STRING do + error_handler.reset log.write_information (generator + ".recent_nodes") create l_parameters.make (2) l_parameters.put (a_rows, "rows") @@ -73,6 +81,7 @@ feature -- Access local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".node") create l_parameters.make (1) l_parameters.put (a_id,"id") @@ -89,6 +98,7 @@ feature -- Access local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".count") create l_parameters.make (0) db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters)) @@ -105,6 +115,7 @@ feature -- Access local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".last_inserted_node_id") create l_parameters.make (0) db_handler.set_query (create {DATABASE_QUERY}.data_reader (Sql_last_insert_node_id, l_parameters)) @@ -122,6 +133,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".new_node") create l_parameters.make (7) l_parameters.put (a_node.title, "title") @@ -140,10 +152,7 @@ feature -- Basic operations db_handler.execute_change a_node.set_id (last_inserted_node_id) - post_execution - - end update_node_title (a_id: INTEGER_64; a_title: READABLE_STRING_32) @@ -151,6 +160,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".update_node_title") create l_parameters.make (3) l_parameters.put (a_title, "title") @@ -166,6 +176,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".update_node_summary") create l_parameters.make (3) l_parameters.put (a_summary, "summary") @@ -181,6 +192,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".update_node_content") create l_parameters.make (3) l_parameters.put (a_content, "content") @@ -196,6 +208,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".update_node") create l_parameters.make (7) l_parameters.put (a_node.title, "title") @@ -215,6 +228,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".delete_node") create l_parameters.make (1) l_parameters.put (a_id, "id") @@ -227,6 +241,7 @@ feature -- Basic operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".delete_from_user_nodes") create l_parameters.make (1) l_parameters.put (a_id, "id") @@ -242,6 +257,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [detachable ANY] do + error_handler.reset log.write_information (generator + ".add_author") create l_parameters.make (2) l_parameters.put (a_user_id,"user_id") @@ -256,6 +272,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [detachable ANY] do + error_handler.reset log.write_information (generator + ".add_collaborator") create l_parameters.make (2) l_parameters.put (a_user_id,"users_id") @@ -270,6 +287,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [detachable ANY] do + error_handler.reset log.write_information (generator + ".add_collaborator") create l_parameters.make (2) l_parameters.put (a_user_id,"users_id") @@ -285,6 +303,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".author_nodes") create l_parameters.make (1) l_parameters.put (a_id, "user_id") @@ -299,6 +318,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".collaborator_nodes") create l_parameters.make (1) l_parameters.put (a_id, "user_id") @@ -314,6 +334,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".node_author") create l_parameters.make (1) l_parameters.put (a_id, "node_id") @@ -330,6 +351,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".node_collaborators") create l_parameters.make (1) l_parameters.put (a_id, "node_id") @@ -344,6 +366,7 @@ feature -- Basic Operations: User_Nodes local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".node_collaborators") create l_parameters.make (2) l_parameters.put (a_user_id, "user_id") @@ -353,7 +376,6 @@ feature -- Basic Operations: User_Nodes if db_handler.count = 1 then Result := db_handler.read_integer_32 (1) = 1 end - post_execution end @@ -480,6 +502,10 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do + error_handler.add_synchronization (db_handler.database_error_handler) + if error_handler.has_error then + log.write_critical (generator + ".post_execution " + error_handler.as_string_representation) + end end end diff --git a/persistence/implementation/mysql/src/provider/user_data_provider.e b/persistence/implementation/mysql/src/provider/user_data_provider.e index 0d9b0bf..8660b8e 100644 --- a/persistence/implementation/mysql/src/provider/user_data_provider.e +++ b/persistence/implementation/mysql/src/provider/user_data_provider.e @@ -10,10 +10,10 @@ inherit PARAMETER_NAME_HELPER - SHARED_ERROR - REFACTORING_HELPER + SHARED_LOGGER + create make @@ -23,17 +23,24 @@ feature -- Initialization -- Create a data provider. do create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection) + create error_handler.make post_execution end db_handler: DATABASE_HANDLER -- Db handler. +feature -- Error Handler + + error_handler: ERROR_HANDLER + + feature -- Status Report is_successful: BOOLEAN -- Is the last execution sucessful? do + Result := not error_handler.has_error end has_user: BOOLEAN @@ -51,6 +58,7 @@ feature -- Basic Operations l_password_salt, l_password_hash: STRING l_security: SECURITY_PROVIDER do + error_handler.reset create l_security l_password_salt := l_security.salt l_password_hash := l_security.password_hash (a_password, l_password_salt) @@ -71,6 +79,7 @@ feature -- Basic Operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".user") create l_parameters.make (1) l_parameters.put (a_id,"id") @@ -87,6 +96,7 @@ feature -- Basic Operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".user_by_name") create l_parameters.make (1) l_parameters.put (a_name,"name") @@ -104,6 +114,7 @@ feature -- Basic Operations local l_parameters: STRING_TABLE [detachable ANY] do + error_handler.reset log.write_information (generator + ".user_by_email") create l_parameters.make (1) l_parameters.put (a_email,"email") @@ -120,6 +131,7 @@ feature -- Basic Operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".user_salt") create l_parameters.make (1) l_parameters.put (a_username,"name") @@ -138,6 +150,7 @@ feature -- Basic Operations local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".count") create l_parameters.make (0) db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters)) @@ -155,6 +168,7 @@ feature -- Basic operations: User Roles local l_parameters: STRING_TABLE [detachable ANY] do + error_handler.reset log.write_information (generator + ".add_role") create l_parameters.make (2) l_parameters.put (a_user_id,"users_id") @@ -169,6 +183,7 @@ feature -- Basic operations: User Roles local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".user_roles") create l_parameters.make (1) l_parameters.put (a_id, "user_id") @@ -186,6 +201,7 @@ feature -- Basic operations: User Profiles local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".save_profile_item") create l_parameters.make (3) l_parameters.put (a_key, "key") @@ -201,6 +217,7 @@ feature -- Basic operations: User Profiles local l_cursor: TABLE_ITERATION_CURSOR [READABLE_STRING_8, READABLE_STRING_8] do + error_handler.reset log.write_information (generator + ".save_profile") from l_cursor := a_user_profile.new_cursor @@ -219,6 +236,7 @@ feature -- Basic operations: User Profiles local l_parameters: STRING_TABLE [ANY] do + error_handler.reset log.write_information (generator + ".user_profile") create l_parameters.make (1) l_parameters.put (a_user_id, "users_id") @@ -310,6 +328,10 @@ feature {NONE} -- Implementation post_execution -- Post database execution. do + error_handler.add_synchronization (db_handler.database_error_handler) + if error_handler.has_error then + log.write_critical (generator + ".post_execution " + error_handler.as_string_representation) + end end end diff --git a/persistence/implementation/mysql/tests/handler/database_handler_test.e b/persistence/implementation/mysql/tests/handler/database_handler_test.e new file mode 100644 index 0000000..6ae64b4 --- /dev/null +++ b/persistence/implementation/mysql/tests/handler/database_handler_test.e @@ -0,0 +1,81 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + DATABASE_HANDLER_TEST + +inherit + EQA_TEST_SET + redefine + on_prepare, + on_clean + select + default_create + end + ABSTRACT_DB_TEST + rename + default_create as default_db_test + end + + +feature {NONE} -- Events + + on_prepare + -- + do + (create {CLEAN_DB}).clean_db(connection) + end + + on_clean + -- + do + end + + +feature -- Test routines + + test_wrong_database_query + -- New test routine + local + l_parameters: STRING_TABLE[detachable ANY] + do + create l_parameters.make (0) + handler.set_query (create {DATABASE_QUERY}.data_reader ("Sellect from users", l_parameters)) + handler.execute_query + assert ("Has error:", handler.has_error) + end + + + + test_sequences_of_wrong_and_correct_queries + -- New test routine + local + l_parameters: STRING_TABLE[detachable ANY] + do + create l_parameters.make (0) + handler.set_query (create {DATABASE_QUERY}.data_reader ("Sellect from users;", l_parameters)) + handler.execute_query + assert ("Has error:", handler.has_error) + + handler.set_query (create {DATABASE_QUERY}.data_reader ("Select * from users;", l_parameters)) + handler.execute_query + assert ("Not Has error:",not handler.has_error) + end + + +feature -- Handler + + handler: DATABASE_HANDLER + once + create {DATABASE_HANDLER_IMPL} Result.make (connection ) + end + +end + + diff --git a/persistence/implementation/mysql/tests/nodes/node_test_set.e b/persistence/implementation/mysql/tests/nodes/node_test_set.e index 7993a72..9b3b442 100644 --- a/persistence/implementation/mysql/tests/nodes/node_test_set.e +++ b/persistence/implementation/mysql/tests/nodes/node_test_set.e @@ -41,7 +41,9 @@ feature {NONE} -- Events feature -- Test routines test_new_node - do + note + testing: "execution/isolated" + do assert ("Empty Nodes", node_provider.nodes.after) node_provider.new_node (default_node) assert ("Not empty Nodes after new_node", not node_provider.nodes.after) @@ -53,6 +55,8 @@ feature -- Test routines test_update_node + note + testing: "execution/isolated" local l_node: CMS_NODE do @@ -85,6 +89,8 @@ feature -- Test routines end test_update_title + note + testing: "execution/isolated" local l_node: CMS_NODE do @@ -104,6 +110,8 @@ feature -- Test routines end test_update_summary + note + testing: "execution/isolated" local l_node: CMS_NODE do @@ -123,11 +131,14 @@ feature -- Test routines end test_update_content + note + testing: "execution/isolated" local l_node: CMS_NODE do assert ("Empty Nodes", node_provider.nodes.after) l_node := custom_node ("

test node udpate

", "Update node", "Test case update") + connection.begin_transaction node_provider.new_node (l_node) assert ("Not empty Nodes after new_node", not node_provider.nodes.after) -- Exist node with id 1 @@ -139,6 +150,7 @@ feature -- Test routines node_provider.update_node_content (l_un.id,"New Content") assert ("Exist node with id 1", attached {CMS_NODE} node_provider.node (1) as ll_node and then not (ll_node.content ~ l_un.content) and then ll_node.content ~ "New Content" and then ll_node.summary ~ l_un.summary and then ll_node.title ~ l_un.title) end + connection.commit end diff --git a/persistence/implementation/mysql/tests/tests.ecf b/persistence/implementation/mysql/tests/tests.ecf index 363c33c..abe2c75 100644 --- a/persistence/implementation/mysql/tests/tests.ecf +++ b/persistence/implementation/mysql/tests/tests.ecf @@ -7,6 +7,7 @@ + diff --git a/persistence/implementation/mysql/tests/transactions/transaction_test_set.e b/persistence/implementation/mysql/tests/transactions/transaction_test_set.e index 3199f71..4abdd8c 100644 --- a/persistence/implementation/mysql/tests/transactions/transaction_test_set.e +++ b/persistence/implementation/mysql/tests/transactions/transaction_test_set.e @@ -66,77 +66,6 @@ feature -- Test routines assert ("Not has nodes:", node_provider.count = 0) end - - - test_user_node_nested_transaction_with_rollback_not_supported - note - testing: "execution/isolated" - do - connection.begin_transaction2 - user_provider.new_user ("test", "test","test@admin.com") - assert ("Has user:", user_provider.has_user) - node_provider.new_node (default_node) - assert ("Has one node:", node_provider.count = 1) - - connection.begin_transaction2 - user_provider.new_user ("test1", "test1","test1@admin.com") - assert ("Has user: test1", attached user_provider.user_by_name ("test1")) - connection.rollback2 - - connection.commit2 - assert ("Has user test:", attached user_provider.user_by_name ("test")) - assert ("Has nodes:", node_provider.count = 1) - assert ("Not has user: test1", user_provider.user_by_name ("test1") = Void) - end - - - test_user_node_nested_transaction_with_commit - note - testing: "execution/isolated" - do - connection.begin_transaction2 - user_provider.new_user ("test", "test","test@admin.com") - assert ("Has user:", user_provider.has_user) - node_provider.new_node (default_node) - assert ("Has one node:", node_provider.count = 1) - - connection.begin_transaction2 - user_provider.new_user ("test1", "test1","test1@admin.com") - assert ("Has user: test1", attached user_provider.user_by_name ("test1")) - connection.commit2 - - connection.commit2 - assert ("Has user test:", attached user_provider.user_by_name ("test")) - assert ("Has user test1:", attached user_provider.user_by_name ("test1")) - assert ("Has nodes:", node_provider.count = 1) - end - - - test_user_node_nested_transaction_with_rollback - note - testing: "execution/isolated" - do - connection.begin_transaction2 - user_provider.new_user ("test", "test","test@admin.com") - assert ("Has user:", user_provider.has_user) - node_provider.new_node (default_node) - assert ("Has one node:", node_provider.count = 1) - - connection.begin_transaction2 - user_provider.new_user ("test1", "test1","test1@admin.com") - assert ("Has user: test1", attached user_provider.user_by_name ("test1")) - connection.commit2 - - connection.rollback2 - assert ("Not Has user test:", user_provider.user_by_name ("test") = void) - assert ("Not Has user test1:", user_provider.user_by_name ("test1") = void) - assert ("Has 0 nodes:", node_provider.count = 0) - end - - - - - feature {NONE} -- Implementation node_provider: NODE_DATA_PROVIDER diff --git a/persistence/interface/cms_storage.e b/persistence/interface/cms_storage.e index eb5a44a..234613d 100644 --- a/persistence/interface/cms_storage.e +++ b/persistence/interface/cms_storage.e @@ -11,7 +11,7 @@ deferred class inherit - SHARED_ERROR + SHARED_LOGGER feature {NONE} -- Initialization @@ -19,6 +19,11 @@ feature {NONE} -- Initialization do end +feature -- Error Handling + + error_handler: ERROR_HANDLER + -- Error handler. + feature -- Access: user has_user: BOOLEAN From b11462105ae35add2fb328fcf2c5ac3cd2c36403 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Mon, 3 Nov 2014 12:40:54 -0300 Subject: [PATCH 09/20] Initial implementation with Hooks, Regions and Templates Updated Modules to support hooks, still work in progress. --- cms/cms-safe.ecf | 6 +- cms/src/hooks/cms_hook.e | 9 + cms/src/hooks/cms_hook_auto_register.e | 33 ++ cms/src/hooks/cms_hook_block.e | 23 + cms/src/hooks/cms_hook_form_alter.e | 17 + cms/src/hooks/cms_hook_menu_alter.e | 17 + cms/src/hooks/cms_hook_value_alter.e | 28 + cms/src/kernel/cms_common_api.e | 97 +++ cms/src/kernel/content/cms_block.e | 28 + cms/src/kernel/content/cms_block_region.e | 42 ++ cms/src/kernel/content/cms_content_block.e | 74 +++ cms/src/kernel/content/cms_menu_block.e | 41 ++ cms/src/kernel/content/cms_value_table.e | 89 +++ cms/src/kernel/content/format/cms_formats.e | 64 ++ cms/src/kernel/form/cms_form.e | 42 ++ cms/src/kernel/link/cms_menu_system.e | 88 +++ .../modules/basic_auth/basic_auth_module.e | 7 + .../handler/basic_auth_logoff_handler.e | 2 +- cms/src/modules/cms_module.e | 11 + .../node/handler/node_content_handler.e | 12 +- cms/src/modules/node/handler/node_handler.e | 12 +- .../node/handler/node_summary_handler.e | 12 +- .../modules/node/handler/node_title_handler.e | 12 +- cms/src/modules/node/handler/nodes_handler.e | 2 +- cms/src/modules/node/node_module.e | 41 ++ cms/src/service/filter/cms_error_filter.e | 2 +- cms/src/service/handler/cms_root_handler.e | 2 +- cms/src/service/response/cms_response.e | 557 +++++++++++++++++- cms/src/theme/cms_theme.e | 72 ++- .../theme/default_theme/default_cms_theme.e | 41 +- cms/src/theme/smarty_theme/smarty_cms_theme.e | 27 +- .../roc_api/modules/demo/cms_demo_module.e | 7 + examples/roc_api/site/config/cms.ini | 2 +- .../roc_api/site/www/themes/api/layout.tpl | 36 ++ examples/roc_api/site/www/themes/bootstrap.7z | Bin 0 -> 2576 bytes .../site/www/themes/bootstrap/layout.tpl | 64 ++ .../site/www/themes/bootstrap/page.tpl | 64 ++ .../www/themes/bootstrap/roc_template.html | 86 +++ .../site/www/themes/bootstrap/theme.info | 13 + .../www/themes/bootstrap/tpl/help_section.tpl | 1 + .../bootstrap/tpl/highlighted_section.tpl | 1 + .../www/themes/bootstrap/tpl/left_sidebar.tpl | 8 + .../www/themes/bootstrap/tpl/main_content.tpl | 4 + .../www/themes/bootstrap/tpl/page_bottom.tpl | 0 .../www/themes/bootstrap/tpl/page_footer.tpl | 9 + .../www/themes/bootstrap/tpl/page_header.tpl | 10 + .../www/themes/bootstrap/tpl/page_top.tpl | 0 .../themes/bootstrap/tpl/right_sidebar.tpl | 8 + model/src/cms_link.e | 11 +- model/src/cms_local_link.e | 21 + 50 files changed, 1810 insertions(+), 45 deletions(-) create mode 100644 cms/src/hooks/cms_hook.e create mode 100644 cms/src/hooks/cms_hook_auto_register.e create mode 100644 cms/src/hooks/cms_hook_block.e create mode 100644 cms/src/hooks/cms_hook_form_alter.e create mode 100644 cms/src/hooks/cms_hook_menu_alter.e create mode 100644 cms/src/hooks/cms_hook_value_alter.e create mode 100644 cms/src/kernel/cms_common_api.e create mode 100644 cms/src/kernel/content/cms_block.e create mode 100644 cms/src/kernel/content/cms_block_region.e create mode 100644 cms/src/kernel/content/cms_content_block.e create mode 100644 cms/src/kernel/content/cms_menu_block.e create mode 100644 cms/src/kernel/content/cms_value_table.e create mode 100644 cms/src/kernel/content/format/cms_formats.e create mode 100644 cms/src/kernel/form/cms_form.e create mode 100644 cms/src/kernel/link/cms_menu_system.e create mode 100644 examples/roc_api/site/www/themes/api/layout.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap.7z create mode 100644 examples/roc_api/site/www/themes/bootstrap/layout.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/page.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/roc_template.html create mode 100644 examples/roc_api/site/www/themes/bootstrap/theme.info create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/help_section.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/highlighted_section.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/left_sidebar.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/main_content.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/page_bottom.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/page_footer.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/page_top.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/right_sidebar.tpl diff --git a/cms/cms-safe.ecf b/cms/cms-safe.ecf index 3a5945e..e8f43fa 100644 --- a/cms/cms-safe.ecf +++ b/cms/cms-safe.ecf @@ -10,7 +10,9 @@ - + + + @@ -18,6 +20,8 @@ + + /EIFGENs$ diff --git a/cms/src/hooks/cms_hook.e b/cms/src/hooks/cms_hook.e new file mode 100644 index 0000000..83f9ac3 --- /dev/null +++ b/cms/src/hooks/cms_hook.e @@ -0,0 +1,9 @@ +note + description: "Marker interface" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_HOOK + +end diff --git a/cms/src/hooks/cms_hook_auto_register.e b/cms/src/hooks/cms_hook_auto_register.e new file mode 100644 index 0000000..d960b6d --- /dev/null +++ b/cms/src/hooks/cms_hook_auto_register.e @@ -0,0 +1,33 @@ +note + description: "[ + Summary description for {CMS_HOOK_AUTO_REGISTER}. + When inheriting from this class, the declared hooks are automatically + registered, otherwise, each descendant has to add it to the cms service + itself. + ]" + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + revision: "$Revision: 95708 $" + +deferred class + CMS_HOOK_AUTO_REGISTER + +inherit + CMS_HOOK + +feature -- Hook + + hook_auto_register (a_response: CMS_RESPONSE) + do + if attached {CMS_HOOK_MENU_ALTER} Current as h_menu_alter then + a_response.add_menu_alter_hook (h_menu_alter) + end + if attached {CMS_HOOK_BLOCK} Current as h_block then + a_response.add_block_hook (h_block) + end + if attached {CMS_HOOK_FORM_ALTER} Current as h_block then + a_response.add_form_alter_hook (h_block) + end + + end + +end diff --git a/cms/src/hooks/cms_hook_block.e b/cms/src/hooks/cms_hook_block.e new file mode 100644 index 0000000..54b493a --- /dev/null +++ b/cms/src/hooks/cms_hook_block.e @@ -0,0 +1,23 @@ +note + description: "Summary description for {CMS_HOOK_BLOCK}." + author: "" + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + revision: "$Revision: 95708 $" + +deferred class + CMS_HOOK_BLOCK + +inherit + CMS_HOOK + +feature -- Hook + + block_list: ITERABLE [like {CMS_BLOCK}.name] + deferred + end + + get_block_view (a_block_id: detachable READABLE_STRING_8; a_response: CMS_RESPONSE) + deferred + end + +end diff --git a/cms/src/hooks/cms_hook_form_alter.e b/cms/src/hooks/cms_hook_form_alter.e new file mode 100644 index 0000000..472979c --- /dev/null +++ b/cms/src/hooks/cms_hook_form_alter.e @@ -0,0 +1,17 @@ +note + description: "Describe how to alter a form before it's rendered" + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + +deferred class + CMS_HOOK_FORM_ALTER + +inherit + CMS_HOOK + +feature -- Hook + + form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; a_response: CMS_RESPONSE) + deferred + end + +end diff --git a/cms/src/hooks/cms_hook_menu_alter.e b/cms/src/hooks/cms_hook_menu_alter.e new file mode 100644 index 0000000..d409662 --- /dev/null +++ b/cms/src/hooks/cms_hook_menu_alter.e @@ -0,0 +1,17 @@ +note + description: "Describe how to alter a menu before it's rendered." + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + +deferred class + CMS_HOOK_MENU_ALTER + +inherit + CMS_HOOK + +feature -- Hook + + menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) + deferred + end + +end diff --git a/cms/src/hooks/cms_hook_value_alter.e b/cms/src/hooks/cms_hook_value_alter.e new file mode 100644 index 0000000..0ec43b9 --- /dev/null +++ b/cms/src/hooks/cms_hook_value_alter.e @@ -0,0 +1,28 @@ +note + description: "Describe how to alter generic values before they are rendered." + date: "$Date: 2014-10-23 08:30:11 -0300 (ju. 23 de oct. de 2014) $" + revision: "$Revision: 95980 $" + +deferred class + CMS_HOOK_VALUE_ALTER + +inherit + + CMS_HOOK + +feature -- Hook + + value_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) + deferred + 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 diff --git a/cms/src/kernel/cms_common_api.e b/cms/src/kernel/cms_common_api.e new file mode 100644 index 0000000..9301ddf --- /dev/null +++ b/cms/src/kernel/cms_common_api.e @@ -0,0 +1,97 @@ +note + description: "Summary description for {WSF_CMS_COMMON_API}." + author: "" + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + revision: "$Revision: 95708 $" + +deferred class + CMS_COMMON_API + +inherit + WSF_API_UTILITIES + +feature {NONE} -- Access + + site_url: READABLE_STRING_8 + do + Result := "" + end + + base_url: detachable READABLE_STRING_8 + -- Base url if any. + do + end + +feature -- Access + + user_link (u: CMS_USER): like link + do + Result := link (u.name, "/user/" + u.id.out, Void) + end + + node_link (n: CMS_NODE): like link + do + Result := link (n.title, "/node/" + n.id.out, Void) + end + + user_url (u: CMS_USER): like url + do + Result := url ("/user/" + u.id.out, Void) + end + + node_url (n: CMS_NODE): like url + do + Result := url ("/node/" + n.id.out, Void) + end + +feature -- Helper + + is_empty (s: detachable READABLE_STRING_GENERAL): BOOLEAN + -- Is `s' is Void or empty ? + do + Result := s = Void or else s.is_empty + end + + unix_timestamp (dt: DATE_TIME): INTEGER_64 + do + Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp (dt) + end + + unix_timestamp_to_date_time (t: INTEGER_64): DATE_TIME + do + Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (t) + end + + string_unix_timestamp_to_date_time (s: READABLE_STRING_8): DATE_TIME + do + if s.is_integer_64 then + Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (s.to_integer_64) + else + Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (0) + end + end + +feature {NONE} -- Implementation + + options_boolean (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING; dft: BOOLEAN): BOOLEAN + do + if attached {BOOLEAN} opts.item (k) as h then + Result := h + else + Result := dft + end + end + + options_string (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING): detachable STRING + do + if attached {STRING} opts.item (k) as s then + Result := s + end + end + +-- html_encoder: HTML_ENCODER +-- once ("thread") +-- create Result +-- end + +end diff --git a/cms/src/kernel/content/cms_block.e b/cms/src/kernel/content/cms_block.e new file mode 100644 index 0000000..0b67db7 --- /dev/null +++ b/cms/src/kernel/content/cms_block.e @@ -0,0 +1,28 @@ +note + description: "Summary description for {CMS_BLOCK}." + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + +deferred class + CMS_BLOCK + +feature -- Access + + name: READABLE_STRING_8 + deferred + end + + title: detachable READABLE_STRING_32 + deferred + end + +feature -- status report + + is_enabled: BOOLEAN + +feature -- Conversion + + to_html (a_theme: CMS_THEME): STRING_8 + deferred + end + +end diff --git a/cms/src/kernel/content/cms_block_region.e b/cms/src/kernel/content/cms_block_region.e new file mode 100644 index 0000000..baef14f --- /dev/null +++ b/cms/src/kernel/content/cms_block_region.e @@ -0,0 +1,42 @@ +note + description: "Summary description for {CMS_BLOCK_REGION}." + date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $" + +class + CMS_BLOCK_REGION + +create + make + +feature {NONE} -- Initialization + + make (a_name: like name) + do + name := a_name + create blocks.make (1) + end + +feature -- Access + + name: READABLE_STRING_8 + + blocks: ARRAYED_LIST [CMS_BLOCK] + +feature -- Element change + + extend (b: CMS_BLOCK) + do + blocks.force (b) + 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 diff --git a/cms/src/kernel/content/cms_content_block.e b/cms/src/kernel/content/cms_content_block.e new file mode 100644 index 0000000..8a5f7c1 --- /dev/null +++ b/cms/src/kernel/content/cms_content_block.e @@ -0,0 +1,74 @@ +note + description: "Summary description for {CMS_CONTENT_BLOCK}." + author: "" + date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $" + revision: "$Revision: 96018 $" + +class + CMS_CONTENT_BLOCK + +inherit + CMS_BLOCK + +create + make, + make_raw + +feature {NONE} -- Initialization + + make (a_name: like name; a_title: like title; a_content: like content; a_format: like format) + do + is_enabled := True + name := a_name + title := a_title + content := a_content + format := a_format + end + + make_raw (a_name: like name; a_title: like title; a_content: like content; a_format: like format) + do + make (a_name, a_title, a_content, a_format) + set_is_raw (True) + end + +feature -- Access + + name: READABLE_STRING_8 + + title: detachable READABLE_STRING_32 + + content: READABLE_STRING_8 + + format: CONTENT_FORMAT + +feature -- Status report + + is_raw: BOOLEAN + -- Is raw? + -- If True, do not get wrapped it with block specific div + +feature -- Element change + + set_is_raw (b: BOOLEAN) + do + is_raw := b + end + +feature -- Conversion + + to_html (a_theme: CMS_THEME): STRING_8 + do + Result := content + 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 diff --git a/cms/src/kernel/content/cms_menu_block.e b/cms/src/kernel/content/cms_menu_block.e new file mode 100644 index 0000000..a7a0797 --- /dev/null +++ b/cms/src/kernel/content/cms_menu_block.e @@ -0,0 +1,41 @@ +note + description: "Summary description for {CMS_MENU_BLOCK}." + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + +class + CMS_MENU_BLOCK + +inherit + CMS_BLOCK + +create + make + +feature {NONE} -- Initialization + + make (a_menu: like menu) + do + is_enabled := True + menu := a_menu + name := a_menu.name + title := a_menu.title + end + +feature -- Access + + menu: CMS_MENU + + name: READABLE_STRING_8 + + title: detachable READABLE_STRING_32 + + is_horizontal: BOOLEAN + +feature -- Conversion + + to_html (a_theme: CMS_THEME): STRING_8 + do + Result := a_theme.menu_html (menu, is_horizontal) + end + +end diff --git a/cms/src/kernel/content/cms_value_table.e b/cms/src/kernel/content/cms_value_table.e new file mode 100644 index 0000000..2e5ccc9 --- /dev/null +++ b/cms/src/kernel/content/cms_value_table.e @@ -0,0 +1,89 @@ +note + description: "Summary description for {CMS_VALUE_TABLE}." + date: "$Date: 2014-10-23 08:30:11 -0300 (ju. 23 de oct. de 2014) $" + revision: "$Revision: 95980 $" + +class + CMS_VALUE_TABLE + +inherit + TABLE_ITERABLE [detachable ANY, READABLE_STRING_GENERAL] + +create + make + +feature {NONE} -- Initialization + + make (nb: INTEGER) + do + create table.make (nb) + end + +feature -- Access + + count: INTEGER + -- Number of items. + do + Result := table.count + end + + item (key: READABLE_STRING_GENERAL): detachable ANY + -- Item associated with `key', if present + -- otherwise default value of type `G'. + note + option: stable + do + Result := table.item (key) + end + + has (key: READABLE_STRING_GENERAL): BOOLEAN + -- Has item associated with key `key'? + do + Result := table.has (key) + end + + new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL] + -- + do + Result := table.new_cursor + end + +feature -- Element change + + put (new: detachable ANY; key: READABLE_STRING_GENERAL) + -- Insert `new' with `key' if there is no other item + -- associated with the same key. + do + table.put (new, key) + end + + force (new: detachable ANY; key: READABLE_STRING_GENERAL) + -- Update table so that `new' will be the item associated + -- with `key'. + do + table.force (new, key) + end + + remove (key: READABLE_STRING_GENERAL) + do + table.remove (key) + end + +feature {NONE} -- Duplication + + table: STRING_TABLE [detachable ANY] + +invariant + table_set: table /= Void + +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 diff --git a/cms/src/kernel/content/format/cms_formats.e b/cms/src/kernel/content/format/cms_formats.e new file mode 100644 index 0000000..11823ae --- /dev/null +++ b/cms/src/kernel/content/format/cms_formats.e @@ -0,0 +1,64 @@ +note + description: "Summary description for {CMS_FORMATS}." + author: "" + date: "$Date: 2014-10-16 04:45:23 -0300 (ju. 16 de oct. de 2014) $" + revision: "$Revision: 95932 $" + +class + CMS_FORMATS + +feature -- Access + + format (a_name: like {CONTENT_FORMAT}.name): detachable CONTENT_FORMAT + do + across + all_formats as c + until + Result /= Void + loop + if c.item.name.same_string (a_name) then + Result := c.item + end + end + end + + all_formats: LIST [CONTENT_FORMAT] + once + create {ARRAYED_LIST [CONTENT_FORMAT]} Result.make (3) + Result.force (plain_text) + Result.force (full_html) + Result.force (filtered_html) + end + + default_format: CONTENT_FORMAT + do + Result := plain_text --FIXME + end + + plain_text: PLAIN_TEXT_CONTENT_FORMAT + once + create Result + end + + full_html: FULL_HTML_CONTENT_FORMAT + once + create Result + end + + filtered_html: FILTERED_HTML_CONTENT_FORMAT + once + create Result + 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 diff --git a/cms/src/kernel/form/cms_form.e b/cms/src/kernel/form/cms_form.e new file mode 100644 index 0000000..2038a14 --- /dev/null +++ b/cms/src/kernel/form/cms_form.e @@ -0,0 +1,42 @@ +note + description: "Summary description for {CMS_FORM}." + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + revision: "$Revision: 95708 $" + +class + CMS_FORM + +inherit + WSF_FORM + rename + process as process_form + end + +create + make + +feature -- Basic operation + + prepare (a_response: CMS_RESPONSE) + do + a_response.call_form_alter_hooks (Current, Void) + end + + process (a_response: CMS_RESPONSE) + do + process_form (a_response.request, agent on_prepared (a_response, ?), agent on_processed (a_response, ?)) + end + + on_prepared (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA) + do + a_response.call_form_alter_hooks (Current, fd) + end + + on_processed (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA) + do + if not fd.is_valid or fd.has_error then + a_response.report_form_errors (fd) + end + end + +end diff --git a/cms/src/kernel/link/cms_menu_system.e b/cms/src/kernel/link/cms_menu_system.e new file mode 100644 index 0000000..15978bd --- /dev/null +++ b/cms/src/kernel/link/cms_menu_system.e @@ -0,0 +1,88 @@ +note + description: "Describe the navigation menus." + date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $" + revision: "$Revision: 95708 $" + +class + CMS_MENU_SYSTEM + +inherit + ITERABLE [CMS_MENU] + + REFACTORING_HELPER +create + make + +feature {NONE} -- Initialization + + make + -- Create a predefined manu system + do + to_implement ("Refactor, take the info from a Database or Configuration file.") + create items.make (5) + force (create {CMS_MENU}.make ("main-menu", 3)) + force (create {CMS_MENU}.make_with_title ("management", "Management", 3)) + force (create {CMS_MENU}.make_with_title ("navigation", "Navigation", 3)) + force (create {CMS_MENU}.make_with_title ("user", "User", 3)) + end + +feature -- Access + + item (n: like {CMS_MENU}.name): CMS_MENU + local + m: detachable CMS_MENU + do + m := items.item (n) + if m = Void then + create m.make (n, 3) + force (m) + end + Result := m + end + + main_menu: CMS_MENU + do + Result := item ("main-menu") + end + + management_menu: CMS_MENU + do + Result := item ("management") + end + + navigation_menu: CMS_MENU + do + Result := item ("navigation") + end + + user_menu: CMS_MENU + do + Result := item ("user") + end + + primary_tabs: CMS_MENU + do + Result := item ("primary-tabs") + end + +feature -- Change + + force (m: CMS_MENU) + do + items.force (m, m.name) + end + +feature -- Access + + new_cursor: ITERATION_CURSOR [CMS_MENU] + -- Fresh cursor associated with current structure. + do + Result := items.new_cursor + end + +feature {NONE} -- Implementation + + items: HASH_TABLE [CMS_MENU, like {CMS_MENU}.name] +-- items: ARRAYED_LIST [CMS_MENU] + +end diff --git a/cms/src/modules/basic_auth/basic_auth_module.e b/cms/src/modules/basic_auth/basic_auth_module.e index 2c589d1..1afac3e 100644 --- a/cms/src/modules/basic_auth/basic_auth_module.e +++ b/cms/src/modules/basic_auth/basic_auth_module.e @@ -74,4 +74,11 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods) end + +feature -- Hooks + + register_hooks (a_response: CMS_RESPONSE) + do + end + end diff --git a/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e b/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e index b274ab4..ecf3e7b 100644 --- a/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e +++ b/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e @@ -50,7 +50,7 @@ feature -- HTTP Methods if attached req.query_parameter ("prompt") as l_prompt then (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) else - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/basic_auth/logoff") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized) l_page.execute end diff --git a/cms/src/modules/cms_module.e b/cms/src/modules/cms_module.e index a58805e..f7d1eac 100644 --- a/cms/src/modules/cms_module.e +++ b/cms/src/modules/cms_module.e @@ -27,6 +27,17 @@ feature -- Router deferred end + + +feature -- Hooks configuration + + register_hooks (a_response: CMS_RESPONSE) + -- Module hooks configuration. + require + is_enabled: is_enabled + deferred + end + feature -- Filter filters: detachable LIST [WSF_FILTER] diff --git a/cms/src/modules/node/handler/node_content_handler.e b/cms/src/modules/node/handler/node_content_handler.e index 31b911a..4232053 100644 --- a/cms/src/modules/node/handler/node_content_handler.e +++ b/cms/src/modules/node/handler/node_content_handler.e @@ -70,7 +70,7 @@ feature -- HTTP Methods -- 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 {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_content") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (l_node.content, "node_content") l_page.add_variable (l_id.value, "id") l_page.execute @@ -78,7 +78,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -96,14 +96,14 @@ feature -- HTTP Methods if l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end end else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -127,7 +127,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -140,7 +140,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found diff --git a/cms/src/modules/node/handler/node_handler.e b/cms/src/modules/node/handler/node_handler.e index e4257b6..c4e5bf9 100644 --- a/cms/src/modules/node/handler/node_handler.e +++ b/cms/src/modules/node/handler/node_handler.e @@ -69,7 +69,7 @@ feature -- HTTP Methods -- 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 {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup,"modules/node") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (l_node, "node") l_page.execute else @@ -96,7 +96,7 @@ feature -- HTTP Methods elseif l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end end else @@ -131,7 +131,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -151,7 +151,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -165,7 +165,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found @@ -186,7 +186,7 @@ feature {NONE} -- Node l_page: CMS_RESPONSE do if attached current_user_name (req) then - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (setup.is_html, "html") l_page.add_variable (setup.is_web, "web") l_page.execute diff --git a/cms/src/modules/node/handler/node_summary_handler.e b/cms/src/modules/node/handler/node_summary_handler.e index 96f3c36..585a050 100644 --- a/cms/src/modules/node/handler/node_summary_handler.e +++ b/cms/src/modules/node/handler/node_summary_handler.e @@ -69,7 +69,7 @@ feature -- HTTP Methods -- 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 {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_summary") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (l_id.value, "id") l_page.add_variable (l_node.summary, "node_summary") l_page.execute @@ -77,7 +77,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -95,14 +95,14 @@ feature -- HTTP Methods if l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end end else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -125,7 +125,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -140,7 +140,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found diff --git a/cms/src/modules/node/handler/node_title_handler.e b/cms/src/modules/node/handler/node_title_handler.e index a5dfe9d..e1baa7b 100644 --- a/cms/src/modules/node/handler/node_title_handler.e +++ b/cms/src/modules/node/handler/node_title_handler.e @@ -69,7 +69,7 @@ feature -- HTTP Methods -- 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 {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_title") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (l_node.title, "node_title") l_page.add_variable (l_id.value, "id") l_page.execute @@ -77,7 +77,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -94,14 +94,14 @@ feature -- HTTP Methods if l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end end else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -125,7 +125,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -139,7 +139,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found diff --git a/cms/src/modules/node/handler/nodes_handler.e b/cms/src/modules/node/handler/nodes_handler.e index f1097db..4251f70 100644 --- a/cms/src/modules/node/handler/nodes_handler.e +++ b/cms/src/modules/node/handler/nodes_handler.e @@ -52,7 +52,7 @@ feature -- HTTP Methods -- At the moment the template is hardcoded, but we can -- get them from the configuration file and load them into -- the setup class. - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/nodes") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) l_page.add_variable (api_service.nodes, "nodes") l_page.execute end diff --git a/cms/src/modules/node/node_module.e b/cms/src/modules/node/node_module.e index 1ecaea3..f435b04 100644 --- a/cms/src/modules/node/node_module.e +++ b/cms/src/modules/node/node_module.e @@ -10,6 +10,11 @@ inherit CMS_MODULE + CMS_HOOK_MENU_ALTER + + CMS_HOOK_BLOCK + + create make @@ -115,4 +120,40 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods) end + +feature -- Hooks + + register_hooks (a_response: CMS_RESPONSE) + do + a_response.add_menu_alter_hook (Current) + a_response.add_block_hook (Current) + end + + block_list: ITERABLE [like {CMS_BLOCK}.name] + do + Result := <<"node-info">> + end + + get_block_view (a_block_id: detachable READABLE_STRING_8; a_response: CMS_RESPONSE) +-- local +-- b: CMS_CONTENT_BLOCK + do +-- if +-- a_execution.is_front and then +-- attached a_execution.user as u +-- then +-- create b.make ("node-info", "Node", "Node ...", a_execution.formats.plain_text) +-- a_execution.add_block (b, Void) +-- end + end + + menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) + local + lnk: CMS_LOCAL_LINK + perms: detachable ARRAYED_LIST [READABLE_STRING_8] + do + create lnk.make ("node", "/node") + a_menu_system.navigation_menu.extend (lnk) + end + end diff --git a/cms/src/service/filter/cms_error_filter.e b/cms/src/service/filter/cms_error_filter.e index 8a2f154..6a205e1 100644 --- a/cms/src/service/filter/cms_error_filter.e +++ b/cms/src/service/filter/cms_error_filter.e @@ -25,7 +25,7 @@ feature -- Basic operations execute_next (req, res) else log.write_critical (generator + ".execute" + setup.error_handler.as_string_representation ) - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute setup.error_handler.reset end end diff --git a/cms/src/service/handler/cms_root_handler.e b/cms/src/service/handler/cms_root_handler.e index fdb2783..785629f 100644 --- a/cms/src/service/handler/cms_root_handler.e +++ b/cms/src/service/handler/cms_root_handler.e @@ -48,7 +48,7 @@ feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- do - (create {HOME_CMS_RESPONSE}.make (req, res, setup,"layout2")).execute + (create {HOME_CMS_RESPONSE}.make (req, res, setup)).execute end end diff --git a/cms/src/service/response/cms_response.e b/cms/src/service/response/cms_response.e index 671c031..97a5a65 100644 --- a/cms/src/service/response/cms_response.e +++ b/cms/src/service/response/cms_response.e @@ -14,22 +14,44 @@ inherit feature {NONE} -- Initialization - make (req: WSF_REQUEST; res: WSF_RESPONSE; a_setup: like setup; a_template: like template) + make(req: WSF_REQUEST; res: WSF_RESPONSE; a_setup: like setup) do status_code := {HTTP_STATUS_CODE}.ok setup := a_setup request := req response := res - template := a_template create header.make + create values.make (3) initialize end initialize do get_theme + create menu_system.make + initialize_block_region_settings + register_hooks end + + register_hooks + local + l_module: CMS_MODULE + l_available_modules: CMS_MODULE_COLLECTION + do +-- log.write_debug (generator + ".register_hooks") + l_available_modules := setup.modules + across + l_available_modules as ic + loop + l_module := ic.item + if l_module.is_enabled then + l_module.register_hooks (Current) + end + end + end + + feature -- Access request: WSF_REQUEST @@ -50,8 +72,9 @@ feature -- Access main_content: detachable STRING_8 - template: READABLE_STRING_32 - -- Current template. + values: CMS_VALUE_TABLE + -- Associated values indexed by string name. + feature -- Element change @@ -71,6 +94,423 @@ feature -- Element change main_content := s end + +feature -- Formats + + formats: CMS_FORMATS + once + create Result + end + +feature -- Menu + + menu_system: CMS_MENU_SYSTEM + + main_menu: CMS_MENU + do + Result := menu_system.main_menu + end + + management_menu: CMS_MENU + do + Result := menu_system.management_menu + end + + navigation_menu: CMS_MENU + do + Result := menu_system.navigation_menu + end + + user_menu: CMS_MENU + do + Result := menu_system.user_menu + end + + primary_tabs: CMS_MENU + do + Result := menu_system.primary_tabs + debug + end + end + +feature -- Blocks initialization + + initialize_block_region_settings + local + l_table: like block_region_settings + do + create regions.make_caseless (5) + + -- FIXME: let the user choose ... + create l_table.make_caseless (10) + l_table["page_top"] := "top" + l_table["header"] := "header" + l_table["highlighted"] := "highlighted" + l_table["help"] := "help" + l_table["content"] := "content" + l_table["footer"] := "footer" + l_table["management"] := "first_sidebar" + l_table["navigation"] := "first_sidebar" + l_table["user"] := "first_sidebar" + l_table["page_bottom"] := "page_bottom" + block_region_settings := l_table + end + +feature -- Blocks regions + + regions: STRING_TABLE [CMS_BLOCK_REGION] + -- Layout regions, that contains blocks. + + block_region_settings: STRING_TABLE [STRING] + + block_region (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8): CMS_BLOCK_REGION + -- Region associated with block `b', or else `a_default_region' if provided. + local + l_region_name: detachable READABLE_STRING_8 + do + l_region_name := block_region_settings.item (b.name) + if l_region_name = Void then + if a_default_region /= Void then + l_region_name := a_default_region + else + -- Default .. put it in same named region + -- Maybe a bad idea + + l_region_name := b.name.as_lower + end + end + if attached regions.item (l_region_name) as res then + Result := res + else + create Result.make (l_region_name) + regions.force (Result, l_region_name) + end + end + + +feature -- Blocks + + add_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8) + -- Add block `b' to associated region or `a_default_region' if provided. + local + l_region: detachable like block_region + do + l_region := block_region (b, a_default_region) + l_region.extend (b) + end + + get_blocks + do + fixme ("find a way to have this in configuration or database, and allow different order") + add_block (top_header_block, "header") + add_block (header_block, "header") + if attached message_block as m then + add_block (m, "content") + end + -- FIXME: avoid hardcoded html! should be only in theme. + add_block (create {CMS_CONTENT_BLOCK}.make_raw ("top_content_anchor", Void, "%N", formats.full_html), "content") + if attached page_title as l_page_title then + -- FIXME: avoid hardcoded html! should be only in theme. + add_block (create {CMS_CONTENT_BLOCK}.make_raw ("page_title", Void, "

"+ l_page_title +"

%N", formats.full_html), "content") + end + if attached primary_tabs_block as m then + add_block (m, "content") + end + add_block (content_block, "content") + + if attached management_menu_block as l_block then + add_block (l_block, "first_sidebar") + end + if attached navigation_menu_block as l_block then + add_block (l_block, "first_sidebar") + end + + if attached user_menu_block as l_block then + add_block (l_block, "first_sidebar") + end + + if attached footer_block as l_block then + add_block (l_block, "footer") + end + + hook_block_view + end + + main_menu_block: detachable CMS_MENU_BLOCK + do + if attached main_menu as m and then not m.is_empty then + create Result.make (m) + end + end + + management_menu_block: detachable CMS_MENU_BLOCK + do + if attached management_menu as m and then not m.is_empty then + create Result.make (m) + end + end + + navigation_menu_block: detachable CMS_MENU_BLOCK + do + if attached navigation_menu as m and then not m.is_empty then + create Result.make (m) + end + end + + user_menu_block: detachable CMS_MENU_BLOCK + do + if attached user_menu as m and then not m.is_empty then + create Result.make (m) + end + end + + primary_tabs_block: detachable CMS_MENU_BLOCK + do + if attached primary_tabs as m and then not m.is_empty then + create Result.make (m) + end + end + + top_header_block: CMS_CONTENT_BLOCK + local + s: STRING + do + fixme ("Avoid Hardcoded HTML") + -- create s.make_from_string ("
" + html_encoded (site_name) + "
") + create s.make_empty + s.append ("
") + s.append (theme.menu_html (main_menu, True)) + s.append ("
") + create Result.make ("top_header", Void, s, formats.full_html) + Result.set_is_raw (True) + end + + header_block: CMS_CONTENT_BLOCK + local + s: STRING + do + create s.make_empty + create Result.make ("header", Void, s, formats.full_html) + Result.set_is_raw (True) + end + + message_block: detachable CMS_CONTENT_BLOCK + do + if attached message as m and then not m.is_empty then + create Result.make ("message", Void, "
" + m + "
", formats.full_html) + Result.set_is_raw (True) + end + end + + content_block: CMS_CONTENT_BLOCK + local + s: STRING + do + if attached main_content as l_content then + s := l_content + else + s := "" + debug + s := "No Content" + end + end + create Result.make ("content", Void, s, formats.full_html) + Result.set_is_raw (True) + end + + footer_block: CMS_CONTENT_BLOCK + local + s: STRING + do + create s.make_empty + s.append ("Made with EWF") + create Result.make ("made_with", Void, s, formats.full_html) + end + +feature -- Hook: value alter + + add_value_alter_hook (h: like value_alter_hooks.item) + local + lst: like value_alter_hooks + do + lst := value_alter_hooks + if lst = Void then + create lst.make (1) + value_alter_hooks := lst + end + if not lst.has (h) then + lst.force (h) + end + end + + value_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_VALUE_ALTER] + + call_value_alter_hooks (m: CMS_VALUE_TABLE) + do + if attached value_alter_hooks as lst then + across + lst as c + loop + c.item.value_alter (m, Current) + end + end + end + +feature -- Hook: menu_alter + + add_menu_alter_hook (h: like menu_alter_hooks.item) + local + lst: like menu_alter_hooks + do + lst := menu_alter_hooks + if lst = Void then + create lst.make (1) + menu_alter_hooks := lst + end + if not lst.has (h) then + lst.force (h) + end + end + + menu_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_MENU_ALTER] + + call_menu_alter_hooks (m: CMS_MENU_SYSTEM ) + do + if attached menu_alter_hooks as lst then + across + lst as c + loop + c.item.menu_alter (m, Current) + end + end + end + +feature -- Hook: form_alter + + add_form_alter_hook (h: like form_alter_hooks.item) + local + lst: like form_alter_hooks + do + lst := form_alter_hooks + if lst = Void then + create lst.make (1) + form_alter_hooks := lst + end + if not lst.has (h) then + lst.force (h) + end + end + + form_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_FORM_ALTER] + + call_form_alter_hooks (f: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; ) + do + if attached form_alter_hooks as lst then + across + lst as c + loop + c.item.form_alter (f, a_form_data, Current) + end + end + end + +feature -- Hook: block + + add_block_hook (h: like block_hooks.item) + local + lst: like block_hooks + do + lst := block_hooks + if lst = Void then + create lst.make (1) + block_hooks := lst + end + if not lst.has (h) then + lst.force (h) + end + end + + block_hooks: detachable ARRAYED_LIST [CMS_HOOK_BLOCK] + + hook_block_view + do + if attached block_hooks as lst then + across + lst as c + loop + across + c.item.block_list as blst + loop + c.item.get_block_view (blst.item, Current) + end + end + end + end + +feature -- Message + + add_message (a_msg: READABLE_STRING_8; a_category: detachable READABLE_STRING_8) + local + m: like message + do + m := message + if m = Void then + create m.make (a_msg.count + 9) + message := m + end + if a_category /= Void then + m.append ("
  • ") + else + m.append ("
  • ") + end + m.append (a_msg + "
  • ") + end + + add_notice_message (a_msg: READABLE_STRING_8) + do + add_message (a_msg, "notice") + end + + add_warning_message (a_msg: READABLE_STRING_8) + do + add_message (a_msg, "warning") + end + + add_error_message (a_msg: READABLE_STRING_8) + do + add_message (a_msg, "error") + end + + add_success_message (a_msg: READABLE_STRING_8) + do + add_message (a_msg, "success") + end + + report_form_errors (fd: WSF_FORM_DATA) + require + has_error: not fd.is_valid + do + if attached fd.errors as errs then + across + errs as err + loop + if attached err.item as e then + if attached e.field as l_field then + if attached e.message as e_msg then + add_error_message (e_msg) --"Field [" + l_field.name + "] is invalid. " + e_msg) + else + add_error_message ("Field [" + l_field.name + "] is invalid.") + end + elseif attached e.message as e_msg then + add_error_message (e_msg) + end + end + end + end + end + + message: detachable STRING_8 + feature -- Theme theme: CMS_THEME @@ -86,7 +526,7 @@ feature -- Theme create l_info.make_default end if l_info.engine.is_case_insensitive_equal_general ("smarty") then - create {SMARTY_CMS_THEME} theme.make (setup, l_info, template) + create {SMARTY_CMS_THEME} theme.make (setup, l_info) else create {DEFAULT_CMS_THEME} theme.make (setup, l_info) end @@ -111,6 +551,54 @@ feature -- Generation do common_prepare (page) custom_prepare (page) + + -- Cms values + call_value_alter_hooks (values) + + -- Values Associated with current Execution object. + across + values as ic + loop + page.register_variable (ic.item, ic.key) + end + + -- Specific values + page.register_variable (request.absolute_script_url (""), "site_url") + + -- Additional lines in + + call_menu_alter_hooks (menu_system) + prepare_menu_system (menu_system) + + get_blocks + across + regions as reg_ic + loop + across + reg_ic.item.blocks as ic + loop + if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then + recursive_get_active (l_menu_block.menu, request) + end + end + end + + if attached title as l_title then + page.set_title (l_title) + else + page.set_title ("CMS::" + request.path_info) + end + + -- blocks + across + regions as reg_ic + loop + across + reg_ic.item.blocks as ic + loop + page.add_to_region (theme.block_html (ic.item), reg_ic.item.name) + end + end end common_prepare (page: CMS_HTML_PAGE) @@ -129,6 +617,65 @@ feature -- Generation end + prepare_menu_system (a_menu_system: CMS_MENU_SYSTEM) + do + across + a_menu_system as c + loop + prepare_links (c.item) + end + end + + prepare_links (a_menu: CMS_LINK_COMPOSITE) + local + to_remove: ARRAYED_LIST [CMS_LINK] + do + create to_remove.make (0) + across + a_menu as c + loop + if attached {CMS_LOCAL_LINK} c.item as lm then +-- if attached lm.permission_arguments as perms and then not has_permissions (perms) then +-- to_remove.force (lm) +-- else + -- if lm.permission_arguments is Void , this is permitted +-- lm.get_is_active (request) + if attached {CMS_LINK_COMPOSITE} lm as comp then + prepare_links (comp) + end +-- end + elseif attached {CMS_LINK_COMPOSITE} c.item as comp then + prepare_links (comp) + end + end + across + to_remove as c + loop + a_menu.remove (c.item) + end + end + + recursive_get_active (a_comp: CMS_LINK_COMPOSITE; req: WSF_REQUEST) + -- Update the active status recursively on `a_comp'. + local + ln: CMS_LINK + do + if attached a_comp.items as l_items then + across + l_items as ic + loop + ln := ic.item + if attached {CMS_LOCAL_LINK} ln as l_local then +-- l_local.get_is_active (request) + end + if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then + recursive_get_active (l_comp, req) + end + end + end + end + + feature -- Custom Variables variables: detachable STRING_TABLE[ANY] diff --git a/cms/src/theme/cms_theme.e b/cms/src/theme/cms_theme.e index 4557a61..c970bba 100644 --- a/cms/src/theme/cms_theme.e +++ b/cms/src/theme/cms_theme.e @@ -24,9 +24,18 @@ feature -- Access page_template: CMS_TEMPLATE deferred end - feature -- Conversion + menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8 + -- Render Menu as HTML. + -- A theme will define a menu.tpl + deferred + end + + block_html (a_block: CMS_BLOCK): STRING_8 + deferred + end + page_html (page: CMS_HTML_PAGE): STRING_8 -- Render `page' as html. deferred @@ -34,6 +43,67 @@ feature -- Conversion feature {NONE} -- Implementation + append_cms_link_to (lnk: CMS_LINK; s: STRING_8) + local + cl: STRING + do + create cl.make_empty + if lnk.is_active then + cl.append ("active ") + end + if lnk.is_expandable then + cl.append ("expandable ") + end + if lnk.is_expanded then + cl.append ("expanded ") + end + if cl.is_empty then + s.append ("
  • ") + else + s.append ("
  • ") + end +-- s.append ("" + html_encoded (lnk.title) + "") + if +-- (lnk.is_expanded or lnk.is_collapsed) and then + attached lnk.children as l_children + then + s.append ("
      %N") + across + l_children as c + loop + append_cms_link_to (c.item, s) + end + s.append ("
    ") + end + s.append ("
  • ") + end + + +feature -- Encoders + + url_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8 + local + enc: URL_ENCODER + do + create enc + if s /= Void then + Result := enc.general_encoded_string (s) + else + create Result.make_empty + end + end + + html_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8 + local + enc: HTML_ENCODER + do + create enc + if s /= Void then + Result := enc.general_encoded_string (s) + else + create Result.make_empty + end + end note copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" diff --git a/cms/src/theme/default_theme/default_cms_theme.e b/cms/src/theme/default_theme/default_cms_theme.e index dcf4950..a15cc0d 100644 --- a/cms/src/theme/default_theme/default_cms_theme.e +++ b/cms/src/theme/default_theme/default_cms_theme.e @@ -60,7 +60,46 @@ feature -- Conversion prepare (page: CMS_HTML_PAGE) do --- page.add_style (url ("/theme/style.css", Void), Void) + end + + menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8 + do + create Result.make_from_string ("
    ") + if is_horizontal then + Result.append ("
      %N") + else + Result.append ("
        %N") + end + across + a_menu as c + loop + append_cms_link_to (c.item, Result) + end + Result.append ("
      %N") + Result.append ("
    ") + end + + block_html (a_block: CMS_BLOCK): STRING_8 + local + s: STRING + do + if attached {CMS_CONTENT_BLOCK} a_block as l_content_block and then l_content_block.is_raw then + create s.make_empty + if attached l_content_block.title as l_title then + s.append ("
    " + html_encoded (l_title) + "
    ") + end + s.append (l_content_block.to_html (Current)) + else + create s.make_from_string ("
    ") + if attached a_block.title as l_title then + s.append ("
    " + html_encoded (l_title) + "
    ") + end + s.append ("
    ") + s.append (a_block.to_html (Current)) + s.append ("
    ") + s.append ("
    ") + end + Result := s end page_html (page: CMS_HTML_PAGE): STRING_8 diff --git a/cms/src/theme/smarty_theme/smarty_cms_theme.e b/cms/src/theme/smarty_theme/smarty_cms_theme.e index 2b2e6a4..1debe62 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_theme.e +++ b/cms/src/theme/smarty_theme/smarty_cms_theme.e @@ -10,16 +10,17 @@ class inherit CMS_THEME + REFACTORING_HELPER + create make feature {NONE} -- Initialization - make (a_setup: like setup; a_info: like information; a_template: like template) + make (a_setup: like setup; a_info: like information;) do setup := a_setup information := a_info - template := a_template if attached a_info.item ("template_dir") as s then templates_directory := a_setup.theme_location.extended (s) else @@ -28,15 +29,12 @@ feature {NONE} -- Initialization ensure setup_set: setup = a_setup information_set: information = a_info - template_set: template = a_template end feature -- Access name: STRING = "smarty-CMS" - template: STRING; - templates_directory: PATH information: CMS_THEME_INFORMATION @@ -59,7 +57,7 @@ feature -- Access i := i + 1 end else - l_regions := <<"header", "content", "footer", "first_sidebar", "second_sidebar">> + l_regions := <<"top","header", "content", "footer", "first_sidebar", "second_sidebar","bottom">> end internaL_regions := l_regions end @@ -72,7 +70,7 @@ feature -- Access do tpl := internal_page_template if tpl = Void then - create tpl.make (template, Current) + create tpl.make ("page", Current) internal_page_template := tpl end Result := tpl @@ -80,6 +78,21 @@ feature -- Access feature -- Conversion + menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8 + -- Render Menu as HTML. + -- A theme will define a menu.tpl + do + to_implement ("Add implementation") + Result := "to be implemented" + end + + + block_html (a_block: CMS_BLOCK): STRING_8 + do + to_implement ("Add implementation") + Result := "to be implemented" + end + prepare (page: CMS_HTML_PAGE) do end diff --git a/examples/roc_api/modules/demo/cms_demo_module.e b/examples/roc_api/modules/demo/cms_demo_module.e index aeabe7b..bdbe811 100644 --- a/examples/roc_api/modules/demo/cms_demo_module.e +++ b/examples/roc_api/modules/demo/cms_demo_module.e @@ -90,4 +90,11 @@ feature -- Mapping helper: uri template agent map_uri_template_with_request_methods (a_router, a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods) end + +feature -- Hooks + + register_hooks (a_response: CMS_RESPONSE) + do + end + end diff --git a/examples/roc_api/site/config/cms.ini b/examples/roc_api/site/config/cms.ini index 27ebf1f..05a3774 100644 --- a/examples/roc_api/site/config/cms.ini +++ b/examples/roc_api/site/config/cms.ini @@ -3,4 +3,4 @@ site.name=EWF Web CMS site.email=your@email.com var-dir=var files-dir=files -theme=api +theme=bootstrap diff --git a/examples/roc_api/site/www/themes/api/layout.tpl b/examples/roc_api/site/www/themes/api/layout.tpl new file mode 100644 index 0000000..6025408 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/layout.tpl @@ -0,0 +1,36 @@ + + + + {include file="master2/head.tpl"/} + + + + + {include file="master2/site_navigation.tpl"/} + +
    +
    +
    +
    + {include file="master2/content.tpl"/} +
    +
    +
    + + + + {if condition="$web"} + {include file="master2/optional_enhancement_js.tpl"/} + {/if} + + {if condition="$html"} + {include file="master2/optional_enhancement_js.tpl"/} + {/if} + + + + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap.7z b/examples/roc_api/site/www/themes/bootstrap.7z new file mode 100644 index 0000000000000000000000000000000000000000..45c941decd6106e4b114e1d7b783924de174214d GIT binary patch literal 2576 zcmV+r3h(tddc3bE8~_8R1VBj52><{90000Z0000000002DVy5>9tcGS(C?@y7g^b< z_3Ec3KE-SU+(51|DEj{Jb*Xm>EK3AK#$20c(M9hS4eBCS$#-k2m@!U0u)?St?(5l? z+J#Qq(R0L!^oXpcSq(LVJ2>W+I%noD=J}g@+KVUX-oB)0#YL*xY7M6Y8y@#j+lS8J zuQ_u<%)3{4^zTxPUcfXA&9na84S!S*mH9R3Pbn9zfC7_T;bHyBM5BXrb+JQvyQSP- zvJmD{7XiIlwe!$*9RO@KTl_d8DhnY2&zeN%F?$2tz2c-$@gHfJFWRqToojIi$1hh0 z($Eh&<=G${%Gk)p6At9TQ}~j^b$&peJ1K?k;S_yX{4?uP5MaAWf|Q1v+0j%~7wKGg zMv(Rr2(z{BoWa-dCdz)JmPk6MK^;SkUVRaYz-})p>|%;FkpyLskBaniTjlO`j}2`k z9m_Y987gMNtR&_^445k+Cr$kP&x6m)y96Q2p#5TBnfjcNj*>_Wkne!iJmI2?b9&6iXtg+mU6Q=BYXGwHitJY_Q6 zF=s%r%Za15gSU3fr(01CYuhrD<54l+jeprX)GY{BSN#3~Xc_Nqy&ndZI0n|WL`0WI z_ExbN2!?_dt-Tom&!Vy%QZ7#r7c&a!yESMPk%}sJwOrjt%gAp;fv-C>Rq$RQ0+Qmg0X4%i!~Zg)Tx5Wk_};uyp0H_IhGAfm^4t? zzk{Kl!#U<}J!}sS33yyyLJWQ`eYIOkcxW&kDn?9-Z@YtAh&&qvNt(4HPAasE`t4Tt zO51jPn6fK~9)#RKGmf!Q5~I=BH!#>TMqR}}D-18`-tSx^lhPqRWr1Uq!wa_7L7t3g zi%sGU=1;4#_hhtTcb$2BFk8mId>A! zZtS8edApwPczvAXv(Uq%26{bY`tCJY-o#%FFYHK>&2;s@U*RgIfmBLw_07ASn3Vk-LQ6GlDOit{9Bs8ve7w$nGg z+06rSY(bWq2|JSp)s5o1bz&#Ige8f+*m=7htIi`e=0VHrMjLV_6$YN!!i&zIGrD=e znNWFLAk<}(l%a{^oAev3$y_i3cJm{jPIuUmZX{X8I26I>UK9;=H<@2H?_1}epO}Zy z1Hh!>FX7i=*S;zCqI(MVPb+0oHZIj$45Wtow(c|b7405Ig&5GIo!QK#qNZx+HdrW3 z-d0Y8#>0f){eK#3jtJx89}y9-D>{vul^H7A1Mw8kxn-@(<+Gi3tHeCK6}k`WOG*wz zB;}al36%cYEO(^0s18z27ZOJ~3!uNQTors?EwSm((|RY+ysUbqBw>{^1jAbVvpbaW zr8~9uX%TBn%U>n1a@rAes`-KnU@- zPKbM)Iv%uTQMn+Vt;0We5P2M7cAUjvg-;-H3#NkZ&9q(fVN$n?v|=8N`XH9O&v79x z!e)>z4Hfuw_sj>8d~*vakZd}rAuT2KILntbZ*PL^t1RA58_|D-rH{q1$(G46kH<28 z?S8MpAQI`uwK~OYpyHS^QIPYs#dxHRZ#(D2U?oo3;W4+$_Mt^nxmAcfCc=Rx9ZTty zb0m&Z#+Zk@sXNi&;(^tDbRM(~RzLH{BoTVbj_$(3)()znx2Ogp61R=com%-@DRlX> zmm!IwR~PiOz(6%-YQ#NmiH$$xWb+HVs{GvAQP?xH_r&d?hK7~{9qh}r@I%v6v)`oNUOvW;}Xy{H7e=_furW6bm!L8U^OCydyt*3m1)Ct?fX6HXL zs{4e;w0e(Oq;klui%08`K5j~Cn1!d`wi_I?I9JLUZei6yA%upS2Twyp(1C1P zq!GRjXNNT8h6N&6PUDq6){*ZsK)VDfnH-8^;zInzYZdkw+b*=5!o7jhi>f}0M9!(u z`bhgi1U3^L2A$^FIzPnt_4WANUW&pS|KF)mXpmHf=Ttb{!xK2%-&F}(%=1D%RJGsS z3gVVa@C8r2X@;w(s7W9j36^5!E6CFKegDOKEJ7(=v{ENfQ8tivcZ(Bkh&6qfwB}NbVUh`gdU7=R$>F+}% zjqnqs2|ESrfTC7pVcNiRz(Y2EpCs1%tFp}9n4C8EV;c`kB5u#TzH4XhL+U0{iJ3F; zG01kCi9Jr+5F8zTAGrOP0yL!SepAgqP9@P2%a|cl-q&cW^JiQxz6V-3S*IR_E8PRO z{pd28_!6_GS#3L6VTvdqxC>5#mZP(x=GP_%P@>k4QFir;Nlq8%w&ulFbKdRlH19-mOASNM$okJeo_q0u_#K6`;ZAD({SK&z?CQ`p0p= zk-q#b5~`&B!jSSI$=Xth7oC5NEd4z>-^>t4lPNR}8nw-~K{Pd*25BHIXgS`#cr(y7 zxR1hG-pwq}12jZE1{doT(3X;x5a%PiFMj8{?YHiT$^v^Qa{0MTZKgmjn>Hq=GTi9k z8}Fq#qUbsWQv*Mf%=-X*si1{Zs`Ba*TwnjNlKT~=kof6TDRWZoM^xGrgQCJwp?dZj z1oAvUq)|NAy>queF?Vbw(+FUFTbB?=ccjbhhRLLzCQgy3+IEGy305p6qe?5zXqoo8 zotTxAh36SEeGT*iE^I!`!{wRlrO85ME8yodrqgs|^hO19UR!Ay;}nhbWmli$a!fps zMo`?!0i2*V?mt=$ByAiHciIIvp)UFuYtbzFQg>(&I_GXA-K9}c74s)6WAbsJqCQ6H m7Y2w`0SSS400#>J00AQd0RaVF01yBG41@;?0cX3}!2kek%Il&4 literal 0 HcmV?d00001 diff --git a/examples/roc_api/site/www/themes/bootstrap/layout.tpl b/examples/roc_api/site/www/themes/bootstrap/layout.tpl new file mode 100644 index 0000000..c2ed53f --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/layout.tpl @@ -0,0 +1,64 @@ + + + + + ROC- Layout with defualt Regions + + + + + + + + +ROC CMS - A responsive layout + + + + {include file="tpl/page_top.tpl"/} + + +
    + + + {include file="tpl/page_header.tpl"/} + + +
    + + + + {include file="tpl/left_sidebar.tpl"/} + + +
    + + {include file="tpl/highlighted_section.tpl"/} + + + + {include file="tpl/help_section.tpl"/} + + + + {include file="tpl/main_content.tpl"/} +
    + + + {include file="tpl/right_sidebar.tpl"/} +
    +
    + + + {include file="tpl/page_footer.tpl"/} + + + {include file="tpl/page_bottom.tpl"/} + + + + diff --git a/examples/roc_api/site/www/themes/bootstrap/page.tpl b/examples/roc_api/site/www/themes/bootstrap/page.tpl new file mode 100644 index 0000000..36952f5 --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/page.tpl @@ -0,0 +1,64 @@ + + + + + ROC- Layout with defualt Regions + + + + + + + + +{$title/} + + + + {$region_top/} + + +
    + + + {$region_header/} + + +
    + + + + {$region_sidebar_first/} + + +
    + + {$region_highlighted/} + + + + {$region_help/} + + + + {$region_main/} +
    + + + {$region_sidebar_second/} +
    +
    + + + {$region_footer/} + + + {$region_bottom/} + + + + diff --git a/examples/roc_api/site/www/themes/bootstrap/roc_template.html b/examples/roc_api/site/www/themes/bootstrap/roc_template.html new file mode 100644 index 0000000..83d6149 --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/roc_template.html @@ -0,0 +1,86 @@ + + + + + ROC- Layout with defualt Regions + + + + + + + + +ROC CMS - A responsive layout + + + + +
    +

    ROC Layout with Defaul Regions

    + +
    + + + + + + + +
    +

    Highlighted Section

    +

    Help Section

    + +

    Main Content Section

    +

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.

    + +

    Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.

    +
    + + + +
    +
    + + + + + + + + + diff --git a/examples/roc_api/site/www/themes/bootstrap/theme.info b/examples/roc_api/site/www/themes/bootstrap/theme.info new file mode 100644 index 0000000..8812944 --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/theme.info @@ -0,0 +1,13 @@ +name=bootstrap +engine=smarty +author=jvelilla +version=0.1 +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 \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/help_section.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/help_section.tpl new file mode 100644 index 0000000..b20cb47 --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/help_section.tpl @@ -0,0 +1 @@ +

    Help Section

    \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/highlighted_section.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/highlighted_section.tpl new file mode 100644 index 0000000..fc75c0c --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/highlighted_section.tpl @@ -0,0 +1 @@ +

    Highlighted Section

    diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/left_sidebar.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/left_sidebar.tpl new file mode 100644 index 0000000..ee2ee4c --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/left_sidebar.tpl @@ -0,0 +1,8 @@ + diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/main_content.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/main_content.tpl new file mode 100644 index 0000000..0df8def --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/main_content.tpl @@ -0,0 +1,4 @@ +

    Main Content Section

    +

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.

    + +

    Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.

    \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/page_bottom.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/page_bottom.tpl new file mode 100644 index 0000000..e69de29 diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/page_footer.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/page_footer.tpl new file mode 100644 index 0000000..9c7ee8e --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/page_footer.tpl @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl new file mode 100644 index 0000000..4cd6c4b --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl @@ -0,0 +1,10 @@ +

    ROC Layout with Default Regions

    + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/page_top.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/page_top.tpl new file mode 100644 index 0000000..e69de29 diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/right_sidebar.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/right_sidebar.tpl new file mode 100644 index 0000000..b0f6904 --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/right_sidebar.tpl @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/model/src/cms_link.e b/model/src/cms_link.e index 7606366..70aca33 100644 --- a/model/src/cms_link.e +++ b/model/src/cms_link.e @@ -29,13 +29,22 @@ feature -- status report end is_expanded: BOOLEAN + -- Is expanded and visually expanded? deferred end + is_collapsed: BOOLEAN + -- Is expanded, but visually collapsed? + deferred + ensure + Result implies is_expandable + end + is_expandable: BOOLEAN + -- Is expandable? deferred end - + has_children: BOOLEAN deferred end diff --git a/model/src/cms_local_link.e b/model/src/cms_local_link.e index 9633fc0..f6bd165 100644 --- a/model/src/cms_local_link.e +++ b/model/src/cms_local_link.e @@ -40,6 +40,12 @@ feature -- Status report Result := is_expandable and then internal_is_expanded end + is_collapsed: BOOLEAN + -- Is expanded, but visually collapsed? + do + Result := is_expandable and then internal_is_collapsed + end + is_expandable: BOOLEAN do Result := internal_is_expandable or internal_is_expanded or has_children @@ -58,6 +64,8 @@ feature -- Status report internal_is_expanded: BOOLEAN + internal_is_collapsed: BOOLEAN + feature -- Element change add_link (lnk: CMS_LINK) @@ -90,11 +98,24 @@ feature -- Element change children := lst end + set_expanded (b: like is_expanded) do + if b then + set_expandable (True) + set_collapsed (False) + end internal_is_expanded := b end + set_collapsed (b: like is_collapsed) + do + if b then + set_expanded (False) + end + internal_is_collapsed := b + end + set_expandable (b: like is_expandable) do internal_is_expandable := b From bafdc085d9d7f2e43121f0e28b5489dfe1ce0d1d Mon Sep 17 00:00:00 2001 From: jvelilla Date: Tue, 4 Nov 2014 11:31:43 -0300 Subject: [PATCH 10/20] Added refactoring helper class to add comments. --- cms/src/service/response/cms_response.e | 8 +- cms/src/theme/cms_html_page.e | 97 ++++++++++--------- cms/src/theme/cms_theme.e | 12 ++- cms/src/theme/cms_theme_information.e | 2 +- .../smarty_theme/smarty_cms_page_template.e | 2 +- cms/src/theme/smarty_theme/smarty_cms_theme.e | 38 ++++++-- .../site/www/themes/bootstrap/page.tpl | 2 +- model/src/cms_local_link.e | 2 - 8 files changed, 99 insertions(+), 64 deletions(-) diff --git a/cms/src/service/response/cms_response.e b/cms/src/service/response/cms_response.e index 97a5a65..56500a0 100644 --- a/cms/src/service/response/cms_response.e +++ b/cms/src/service/response/cms_response.e @@ -143,7 +143,7 @@ feature -- Blocks initialization -- FIXME: let the user choose ... create l_table.make_caseless (10) - l_table["page_top"] := "top" + l_table["top"] := "top" l_table["header"] := "header" l_table["highlighted"] := "highlighted" l_table["help"] := "help" @@ -152,7 +152,7 @@ feature -- Blocks initialization l_table["management"] := "first_sidebar" l_table["navigation"] := "first_sidebar" l_table["user"] := "first_sidebar" - l_table["page_bottom"] := "page_bottom" + l_table["bottom"] := "page_bottom" block_region_settings := l_table end @@ -275,13 +275,13 @@ feature -- Blocks local s: STRING do - fixme ("Avoid Hardcoded HTML") + fixme ("Avoid Hardcoded HTML!!!") -- create s.make_from_string ("
    " + html_encoded (site_name) + "
    ") create s.make_empty s.append ("
    ") s.append (theme.menu_html (main_menu, True)) s.append ("
    ") - create Result.make ("top_header", Void, s, formats.full_html) + create Result.make ("header", Void, s, formats.full_html) Result.set_is_raw (True) end diff --git a/cms/src/theme/cms_html_page.e b/cms/src/theme/cms_html_page.e index 5c6a5c0..1565d07 100644 --- a/cms/src/theme/cms_html_page.e +++ b/cms/src/theme/cms_html_page.e @@ -1,7 +1,8 @@ note description: "Summary description for {CMS_HTML_PAGE}." - date: "$Date$" - revision: "$Revision$" + author: "" + date: "$Date: 2014-11-04 09:57:24 -0300 (ma. 04 de nov. de 2014) $" + revision: "$Revision: 96034 $" class CMS_HTML_PAGE @@ -23,6 +24,7 @@ feature {NONE} -- Initialization do create regions.make (5) language := "en" + status_code := {HTTP_STATUS_CODE}.ok create header.make create {ARRAYED_LIST [STRING]} head_lines.make (5) @@ -65,7 +67,7 @@ feature -- Header feature -- Region - regions: HASH_TABLE [STRING_8, STRING_8] + regions: STRING_TABLE [STRING_8] -- header -- content -- footer @@ -83,21 +85,6 @@ feature -- Region end end - header_region: STRING_8 - do - Result := region ("header") - end - - content_region: STRING_8 - do - Result := region ("content") - end - - footer_region: STRING_8 - do - Result := region ("content") - end - feature -- Element change register_variable (a_value: detachable ANY; k: READABLE_STRING_GENERAL) @@ -118,41 +105,11 @@ feature -- Element change end end - add_to_header_region (s: STRING) - do - add_to_region (s, "header") - end - - add_to_content_region (s: STRING) - do - add_to_region (s, "content") - end - - add_to_footer_region (s: STRING) - do - add_to_region (s, "footer") - end - set_region (s: STRING; k: STRING) do regions.force (s, k) end - set_header_region (s: STRING) - do - set_region (s, "header") - end - - set_content_region (s: STRING) - do - set_region (s, "content") - end - - set_footer_region (s: STRING) - do - set_region (s, "footer") - end - feature -- Element change set_status_code (c: like status_code) @@ -170,6 +127,50 @@ feature -- Element change title := s end + add_meta_name_content (a_name: STRING; a_content: STRING) + local + s: STRING_8 + do + s := "" + head_lines.extend (s) + end + + add_meta_http_equiv (a_http_equiv: STRING; a_content: STRING) + local + s: STRING_8 + do + s := "" + head_lines.extend (s) + end + + add_style (a_href: STRING; a_media: detachable STRING) + local + s: STRING_8 + do + s := "") + head_lines.extend (s) + end + + add_javascript_url (a_src: STRING) + local + s: STRING_8 + do + s := "" + head_lines.extend (s) + end + + add_javascript_content (a_script: STRING) + local + s: STRING_8 + do + s := "" + head_lines.extend (s) + end + note copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/cms/src/theme/cms_theme.e b/cms/src/theme/cms_theme.e index c970bba..441f925 100644 --- a/cms/src/theme/cms_theme.e +++ b/cms/src/theme/cms_theme.e @@ -1,12 +1,16 @@ note description: "Summary description for {WSF_CMS_THEME}." - author: "" date: "$Date$" revision: "$Revision$" deferred class CMS_THEME +inherit + + REFACTORING_HELPER + + feature {NONE} -- Access setup: CMS_SETUP @@ -14,16 +18,20 @@ feature {NONE} -- Access feature -- Access name: STRING + -- theme name. deferred end regions: ARRAY [STRING] + -- theme's regions. deferred end page_template: CMS_TEMPLATE + -- theme template page. deferred end + feature -- Conversion menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8 @@ -33,6 +41,7 @@ feature -- Conversion end block_html (a_block: CMS_BLOCK): STRING_8 + -- Render a block as HTML. deferred end @@ -47,6 +56,7 @@ feature {NONE} -- Implementation local cl: STRING do + fixme ("Remove HTML from Eiffel") create cl.make_empty if lnk.is_active then cl.append ("active ") diff --git a/cms/src/theme/cms_theme_information.e b/cms/src/theme/cms_theme_information.e index ee0800a..719b3c1 100644 --- a/cms/src/theme/cms_theme_information.e +++ b/cms/src/theme/cms_theme_information.e @@ -18,7 +18,7 @@ feature {NONE} -- Initialization create items.make_caseless (1) create regions.make (5) across - (<<"header", "content", "footer", "first_sidebar", "second_sidebar">>) as ic + (<<"top","header", "highlighted","help", "content", "footer", "first_sidebar", "second_sidebar", "bottom">>) as ic loop regions.force (ic.item, ic.item) end diff --git a/cms/src/theme/smarty_theme/smarty_cms_page_template.e b/cms/src/theme/smarty_theme/smarty_cms_page_template.e index b02fe15..188a743 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_page_template.e +++ b/cms/src/theme/smarty_theme/smarty_cms_page_template.e @@ -55,7 +55,7 @@ feature -- Access across theme.regions as r loop - variables.force (page.region (r.item), r.item) + variables.force (page.region (r.item), "region_" + r.item) end end diff --git a/cms/src/theme/smarty_theme/smarty_cms_theme.e b/cms/src/theme/smarty_theme/smarty_cms_theme.e index 1debe62..88ee5aa 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_theme.e +++ b/cms/src/theme/smarty_theme/smarty_cms_theme.e @@ -10,8 +10,6 @@ class inherit CMS_THEME - REFACTORING_HELPER - create make @@ -82,15 +80,43 @@ feature -- Conversion -- Render Menu as HTML. -- A theme will define a menu.tpl do - to_implement ("Add implementation") - Result := "to be implemented" + create Result.make_from_string ("
    ") + if is_horizontal then + Result.append ("
      %N") + else + Result.append ("
        %N") + end + across + a_menu as c + loop + append_cms_link_to (c.item, Result) + end + Result.append ("
      %N") + Result.append ("
    ") end block_html (a_block: CMS_BLOCK): STRING_8 + local + s: STRING do - to_implement ("Add implementation") - Result := "to be implemented" + if attached {CMS_CONTENT_BLOCK} a_block as l_content_block and then l_content_block.is_raw then + create s.make_empty + if attached l_content_block.title as l_title then + s.append ("
    " + html_encoded (l_title) + "
    ") + end + s.append (l_content_block.to_html (Current)) + else + create s.make_from_string ("
    ") + if attached a_block.title as l_title then + s.append ("
    " + html_encoded (l_title) + "
    ") + end + s.append ("
    ") + s.append (a_block.to_html (Current)) + s.append ("
    ") + s.append ("
    ") + end + Result := s end prepare (page: CMS_HTML_PAGE) diff --git a/examples/roc_api/site/www/themes/bootstrap/page.tpl b/examples/roc_api/site/www/themes/bootstrap/page.tpl index 36952f5..54e6aaa 100644 --- a/examples/roc_api/site/www/themes/bootstrap/page.tpl +++ b/examples/roc_api/site/www/themes/bootstrap/page.tpl @@ -13,7 +13,7 @@ -{$title/} +{$page_title/} diff --git a/model/src/cms_local_link.e b/model/src/cms_local_link.e index f6bd165..876b47e 100644 --- a/model/src/cms_local_link.e +++ b/model/src/cms_local_link.e @@ -98,7 +98,6 @@ feature -- Element change children := lst end - set_expanded (b: like is_expanded) do if b then @@ -121,7 +120,6 @@ feature -- Element change internal_is_expandable := b end - set_permission_arguments (args: like permission_arguments) do permission_arguments := args From b90e3b3df0a9eff7fd156b4781ef7f7a16209343 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 5 Nov 2014 07:45:36 -0300 Subject: [PATCH 11/20] Added a CMS_ENCODER utility class. Added a block header template: smarty engine. Added a menu template: smarty engine. --- cms/src/kernel/content/cms_encoders.e | 35 +++++++++ cms/src/modules/node/node_module.e | 4 +- cms/src/service/response/cms_response.e | 76 +++++++++++++++---- cms/src/theme/cms_theme.e | 28 +------ cms/src/theme/smarty_theme/smarty_cms_theme.e | 27 +++---- .../themes/bootstrap/block/header_block.tpl | 7 ++ .../site/www/themes/bootstrap/page.tpl | 4 +- .../site/www/themes/bootstrap/tpl/menu.tpl | 3 + .../www/themes/bootstrap/tpl/page_header.tpl | 2 +- 9 files changed, 126 insertions(+), 60 deletions(-) create mode 100644 cms/src/kernel/content/cms_encoders.e create mode 100644 examples/roc_api/site/www/themes/bootstrap/block/header_block.tpl create mode 100644 examples/roc_api/site/www/themes/bootstrap/tpl/menu.tpl diff --git a/cms/src/kernel/content/cms_encoders.e b/cms/src/kernel/content/cms_encoders.e new file mode 100644 index 0000000..36b60fc --- /dev/null +++ b/cms/src/kernel/content/cms_encoders.e @@ -0,0 +1,35 @@ +note + description: "Summary description for {CMS_ENCODERS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CMS_ENCODERS + +feature -- Encoders + + url_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8 + local + enc: URL_ENCODER + do + create enc + if s /= Void then + Result := enc.general_encoded_string (s) + else + create Result.make_empty + end + end + + html_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8 + local + enc: HTML_ENCODER + do + create enc + if s /= Void then + Result := enc.general_encoded_string (s) + else + create Result.make_empty + end + end +end diff --git a/cms/src/modules/node/node_module.e b/cms/src/modules/node/node_module.e index f435b04..e1e59a5 100644 --- a/cms/src/modules/node/node_module.e +++ b/cms/src/modules/node/node_module.e @@ -152,8 +152,8 @@ feature -- Hooks lnk: CMS_LOCAL_LINK perms: detachable ARRAYED_LIST [READABLE_STRING_8] do - create lnk.make ("node", "/node") - a_menu_system.navigation_menu.extend (lnk) + create lnk.make ("List of nodes", "/nodes") + a_menu_system.main_menu.extend (lnk) end end diff --git a/cms/src/service/response/cms_response.e b/cms/src/service/response/cms_response.e index 56500a0..8927719 100644 --- a/cms/src/service/response/cms_response.e +++ b/cms/src/service/response/cms_response.e @@ -7,6 +7,7 @@ deferred class CMS_RESPONSE inherit + CMS_ENCODERS CMS_REQUEST_UTIL @@ -139,9 +140,10 @@ feature -- Blocks initialization local l_table: like block_region_settings do + fixme ("CHECK:Can we use the same structure as in theme.info?") create regions.make_caseless (5) - -- FIXME: let the user choose ... + fixme ("let the user choose ...") create l_table.make_caseless (10) l_table["top"] := "top" l_table["header"] := "header" @@ -202,7 +204,7 @@ feature -- Blocks get_blocks do fixme ("find a way to have this in configuration or database, and allow different order") - add_block (top_header_block, "header") + add_block (top_header_block, "top") add_block (header_block, "header") if attached message_block as m then add_block (m, "content") @@ -275,22 +277,46 @@ feature -- Blocks local s: STRING do - fixme ("Avoid Hardcoded HTML!!!") - -- create s.make_from_string ("
    " + html_encoded (site_name) + "
    ") create s.make_empty - s.append ("
    ") - s.append (theme.menu_html (main_menu, True)) - s.append ("
    ") - create Result.make ("header", Void, s, formats.full_html) + create Result.make ("page_top", Void, s, formats.full_html) Result.set_is_raw (True) end header_block: CMS_CONTENT_BLOCK local s: STRING + tpl: SMARTY_CMS_PAGE_TEMPLATE + l_page: CMS_HTML_PAGE + l_hb: STRING do - create s.make_empty - create Result.make ("header", Void, s, formats.full_html) + create s.make_from_string (theme.menu_html (main_menu, True)) + create l_hb.make_empty + to_implement ("Check if the tpl does not exist, provide a default implementation") + if attached {SMARTY_CMS_THEME} theme as l_theme then + create tpl.make ("block/header_test", l_theme) + -- Change to "block/header_block" to use the template code. + create l_page.make + l_page.register_variable (s, "header_block") + tpl.prepare (l_page) + l_hb := tpl.to_html (l_page) + end + if l_hb.starts_with ("ERROR") then + l_hb.wipe_out + to_implement ("Hardcoded HTML with CSS, find a better way to define defaults!!!.") + l_hb := "[ + + ]") + + end + create Result.make ("header", Void, l_hb, formats.full_html) Result.set_is_raw (True) end @@ -447,6 +473,25 @@ feature -- Hook: block end end + +feature -- Menu: change + + add_to_main_menu (lnk: CMS_LINK) + do +-- if attached {CMS_LOCAL_LINK} lnk as l_local then +-- l_local.get_is_active (request) +-- end + main_menu.extend (lnk) + end + + add_to_menu (lnk: CMS_LINK; m: CMS_MENU) + do +-- if attached {CMS_LOCAL_LINK} lnk as l_local then +-- l_local.get_is_active (request) +-- end + m.extend (lnk) + end + feature -- Message add_message (a_msg: READABLE_STRING_8; a_category: detachable READABLE_STRING_8) @@ -567,6 +612,7 @@ feature -- Generation -- Additional lines in + add_to_main_menu (create {CMS_LOCAL_LINK}.make ("Home", "/")) call_menu_alter_hooks (menu_system) prepare_menu_system (menu_system) @@ -619,11 +665,11 @@ feature -- Generation prepare_menu_system (a_menu_system: CMS_MENU_SYSTEM) do - across - a_menu_system as c - loop - prepare_links (c.item) - end +-- across +-- a_menu_system as c +-- loop +-- prepare_links (c.item) +-- end end prepare_links (a_menu: CMS_LINK_COMPOSITE) diff --git a/cms/src/theme/cms_theme.e b/cms/src/theme/cms_theme.e index 441f925..14b1d9d 100644 --- a/cms/src/theme/cms_theme.e +++ b/cms/src/theme/cms_theme.e @@ -7,6 +7,7 @@ deferred class CMS_THEME inherit + CMS_ENCODERS REFACTORING_HELPER @@ -88,33 +89,6 @@ feature {NONE} -- Implementation s.append ("") end - -feature -- Encoders - - url_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8 - local - enc: URL_ENCODER - do - create enc - if s /= Void then - Result := enc.general_encoded_string (s) - else - create Result.make_empty - end - end - - html_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8 - local - enc: HTML_ENCODER - do - create enc - if s /= Void then - Result := enc.general_encoded_string (s) - else - create Result.make_empty - end - end - note copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/cms/src/theme/smarty_theme/smarty_cms_theme.e b/cms/src/theme/smarty_theme/smarty_cms_theme.e index 88ee5aa..39ea5df 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_theme.e +++ b/cms/src/theme/smarty_theme/smarty_cms_theme.e @@ -79,20 +79,21 @@ feature -- Conversion menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8 -- Render Menu as HTML. -- A theme will define a menu.tpl + local + tpl: SMARTY_CMS_PAGE_TEMPLATE + l_page: CMS_HTML_PAGE do - create Result.make_from_string ("
    ") - if is_horizontal then - Result.append ("
      %N") - else - Result.append ("
        %N") - end - across - a_menu as c - loop - append_cms_link_to (c.item, Result) - end - Result.append ("
      %N") - Result.append ("
    ") + to_implement ("Proof of concept to load a Menu from a tpl/menu.tpl.") + to_implement ("In this case the template only take care of links.") + to_implement ("Maybe we need a SMARTY_CMS_REGION_TEMPLATE") + to_implement ("Provide a default Menu using HTML hardcoded, maybe using the Default or providing a default implementation in CMS_THEME.menu_html") + -- Use the similar pattern to SMARTY_CMS_PAGE_TEMPLATE, with a different prepare + -- feature. + create tpl.make ("tpl/menu", Current) + create l_page.make + l_page.register_variable (a_menu, "menu") + tpl.prepare (l_page) + Result := tpl.to_html (l_page) end diff --git a/examples/roc_api/site/www/themes/bootstrap/block/header_block.tpl b/examples/roc_api/site/www/themes/bootstrap/block/header_block.tpl new file mode 100644 index 0000000..4a3b24c --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/block/header_block.tpl @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/page.tpl b/examples/roc_api/site/www/themes/bootstrap/page.tpl index 54e6aaa..8ee484d 100644 --- a/examples/roc_api/site/www/themes/bootstrap/page.tpl +++ b/examples/roc_api/site/www/themes/bootstrap/page.tpl @@ -23,8 +23,8 @@
    - {$region_header/} - + {$region_header/} +
    diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/menu.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/menu.tpl new file mode 100644 index 0000000..c91d22c --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/menu.tpl @@ -0,0 +1,3 @@ + {foreach item="item" from="$menu.items"} +
  • {$item.title/}
  • + {/foreach} diff --git a/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl b/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl index 4cd6c4b..b0c3d8f 100644 --- a/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl +++ b/examples/roc_api/site/www/themes/bootstrap/tpl/page_header.tpl @@ -1,4 +1,4 @@ -

    ROC Layout with Default Regions

    +

    {$page_title/}

    +
    ]") end @@ -616,18 +639,19 @@ feature -- Generation call_menu_alter_hooks (menu_system) prepare_menu_system (menu_system) - get_blocks - across - regions as reg_ic - loop - across - reg_ic.item.blocks as ic - loop - if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then - recursive_get_active (l_menu_block.menu, request) - end - end - end + set_blocks (page) +-- get_blocks +-- across +-- regions as reg_ic +-- loop +-- across +-- reg_ic.item.blocks as ic +-- loop +-- if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then +-- recursive_get_active (l_menu_block.menu, request) +-- end +-- end +-- end if attached title as l_title then page.set_title (l_title) @@ -635,16 +659,16 @@ feature -- Generation page.set_title ("CMS::" + request.path_info) end - -- blocks - across - regions as reg_ic - loop - across - reg_ic.item.blocks as ic - loop - page.add_to_region (theme.block_html (ic.item), reg_ic.item.name) - end - end +-- -- blocks +-- across +-- regions as reg_ic +-- loop +-- across +-- reg_ic.item.blocks as ic +-- loop +-- page.add_to_region (theme.block_html (ic.item), reg_ic.item.name) +-- end +-- end end common_prepare (page: CMS_HTML_PAGE) diff --git a/cms/src/theme/smarty_theme/smarty_cms_theme.e b/cms/src/theme/smarty_theme/smarty_cms_theme.e index 39ea5df..1eb14f1 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_theme.e +++ b/cms/src/theme/smarty_theme/smarty_cms_theme.e @@ -88,7 +88,7 @@ feature -- Conversion to_implement ("Maybe we need a SMARTY_CMS_REGION_TEMPLATE") to_implement ("Provide a default Menu using HTML hardcoded, maybe using the Default or providing a default implementation in CMS_THEME.menu_html") -- Use the similar pattern to SMARTY_CMS_PAGE_TEMPLATE, with a different prepare - -- feature. + -- feature create tpl.make ("tpl/menu", Current) create l_page.make l_page.register_variable (a_menu, "menu") diff --git a/examples/roc_api/site/www/template/html/layout2.tpl b/examples/roc_api/site/www/template/html/layout2.tpl deleted file mode 100644 index 34a5659..0000000 --- a/examples/roc_api/site/www/template/html/layout2.tpl +++ /dev/null @@ -1,40 +0,0 @@ - - - - {include file="master2/head.tpl"/} - - - - - {include file="master2/site_navigation.tpl"/} - - - -
    -
    -
    -
    - {include file="master2/content.tpl"/} -
    -
    -
    - - - - {if condition="$web"} - {include file="master2/optional_enhancement_js.tpl"/} - {/if} - - {if condition="$html"} - {include file="master2/optional_enhancement_js.tpl"/} - {/if} - - - - \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/content.tpl b/examples/roc_api/site/www/template/html/master2/content.tpl deleted file mode 100644 index b18c5dd..0000000 --- a/examples/roc_api/site/www/template/html/master2/content.tpl +++ /dev/null @@ -1,11 +0,0 @@ - -
    -

    Top most recent nodes


    - - - {foreach from="$nodes" item="item"} - - {/foreach} -
    diff --git a/examples/roc_api/site/www/template/html/master2/error.tpl b/examples/roc_api/site/www/template/html/master2/error.tpl deleted file mode 100644 index 0ca7ad0..0000000 --- a/examples/roc_api/site/www/template/html/master2/error.tpl +++ /dev/null @@ -1,18 +0,0 @@ -

    Error: {$code/}

    - -{assign name="status400" value="400"/} -{assign name="status404" value="404"/} -{assign name="status500" value="500"/} - -{if condition="$code ~ $status500"} -

    Internal server error, for the request {$request/}

    -{/if} - - -{if condition="$code ~ $status404"} -

    Resourse not found, for the request {$request/}

    -{/if} - -{if condition="$code ~ $status400"} -

    Bad request, the request {$request/} is not valid

    -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/footer.tpl b/examples/roc_api/site/www/template/html/master2/footer.tpl deleted file mode 100644 index 11fe183..0000000 --- a/examples/roc_api/site/www/template/html/master2/footer.tpl +++ /dev/null @@ -1,7 +0,0 @@ - -
    -

    API Documentation     - Questions? Comments? Let us know!

    -

    © Copyright 2014 Eiffel Software -- Privacy Policy -

    -
    \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/head.tpl b/examples/roc_api/site/www/template/html/master2/head.tpl deleted file mode 100644 index 4ba4616..0000000 --- a/examples/roc_api/site/www/template/html/master2/head.tpl +++ /dev/null @@ -1,10 +0,0 @@ - - -Eiffel RESTonCMS -{if condition="$web"} - {include file="master2/optional_styling_css.tpl"/} -{/if} -{if condition="$html"} - {include file="master2/optional_styling_css.tpl"/} -{/if} - diff --git a/examples/roc_api/site/www/template/html/master2/header.tpl b/examples/roc_api/site/www/template/html/master2/header.tpl deleted file mode 100644 index ce8ec71..0000000 --- a/examples/roc_api/site/www/template/html/master2/header.tpl +++ /dev/null @@ -1,2 +0,0 @@ -

    RESTonCMS

    -

    Tagline

    \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/logoff.tpl b/examples/roc_api/site/www/template/html/master2/logoff.tpl deleted file mode 100644 index 8139dc7..0000000 --- a/examples/roc_api/site/www/template/html/master2/logoff.tpl +++ /dev/null @@ -1,5 +0,0 @@ -

    You have successfully signed out

    - -You may want to return - -Press this neat little button:Take Me Home diff --git a/examples/roc_api/site/www/template/html/master2/main_navigation.tpl b/examples/roc_api/site/www/template/html/master2/main_navigation.tpl deleted file mode 100644 index 88365d7..0000000 --- a/examples/roc_api/site/www/template/html/master2/main_navigation.tpl +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/optional_enhancement_js.tpl b/examples/roc_api/site/www/template/html/master2/optional_enhancement_js.tpl deleted file mode 100644 index 1353b83..0000000 --- a/examples/roc_api/site/www/template/html/master2/optional_enhancement_js.tpl +++ /dev/null @@ -1,5 +0,0 @@ - - -{if condition="$web"} - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/optional_styling_css.tpl b/examples/roc_api/site/www/template/html/master2/optional_styling_css.tpl deleted file mode 100644 index f56d770..0000000 --- a/examples/roc_api/site/www/template/html/master2/optional_styling_css.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{if condition="$html"} - - - -{/if} -{if condition="$web"} - - -{/if} diff --git a/examples/roc_api/site/www/template/html/master2/site_navigation.tpl b/examples/roc_api/site/www/template/html/master2/site_navigation.tpl deleted file mode 100644 index a75760c..0000000 --- a/examples/roc_api/site/www/template/html/master2/site_navigation.tpl +++ /dev/null @@ -1,27 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/navigation.tpl b/examples/roc_api/site/www/template/html/modules/navigation.tpl deleted file mode 100644 index ee2d15e..0000000 --- a/examples/roc_api/site/www/template/html/modules/navigation.tpl +++ /dev/null @@ -1,8 +0,0 @@ -{if isset="$user"} - Logoff -{/if} -{unless isset="$user"} - Login - Register -{/unless} -List of Nodes diff --git a/examples/roc_api/site/www/template/html/modules/node.tpl b/examples/roc_api/site/www/template/html/modules/node.tpl deleted file mode 100644 index 0f6173f..0000000 --- a/examples/roc_api/site/www/template/html/modules/node.tpl +++ /dev/null @@ -1,174 +0,0 @@ -{if condition="html"} - - - - {include file="master2/head.tpl"/} - - -{/if} - -{unless condition="$web"} - - {include file="master2/site_navigation.tpl"/} -{/unless} - - -{if condition="html"} - -
    -
    -
    -
    -{/if} - - -
    - {if condition="$web"} - - {/if} - {if condition="$html"} - - {/if} -
    -
    - {if isset="$node"} -
    -
    -
    -
    -

    {$node.title/}

    -
    -
    -
    {$node.content/}
    -
    -
    -
    - {/if} -
    - -
    - {if isset="$user"} -
    -
    -
    - {if isset="$node"} - -
    - {/if} -
    -
    -
    - {if isset="$user"} -
    -
    - - {if isset="$node"} -
    - -
    - Delete Node - -
    - -
    -
    -
    - {/if} -
    - {/if} -
    -
    -
    - -{if condition="html"} -
    -
    -
    -{/if} - - -{if condition="html"} - - - - {include file="master2/optional_enhancement_js.tpl"/} - - - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/node_content.tpl b/examples/roc_api/site/www/template/html/modules/node_content.tpl deleted file mode 100644 index 4825500..0000000 --- a/examples/roc_api/site/www/template/html/modules/node_content.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{if condition="html"} - - - - {include file="master2/head.tpl"/} - - -{/if} - -{unless condition="$web"} - - {include file="master2/site_navigation.tpl"/} -{/unless} - -{if condition="html"} - -
    -
    -
    -
    -{/if} - - -
    -
    -
    - -
    - Edit Node Content - -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    -{if condition="html"} - -
    -
    -
    -{/if} - - -{if condition="html"} - - - - {include file="master2/optional_enhancement_js.tpl"/} - - - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/node_summary.tpl b/examples/roc_api/site/www/template/html/modules/node_summary.tpl deleted file mode 100644 index 24f69e6..0000000 --- a/examples/roc_api/site/www/template/html/modules/node_summary.tpl +++ /dev/null @@ -1,71 +0,0 @@ -{if condition="html"} - - - - {include file="master2/head.tpl"/} - - -{/if} - - - {unless condition="$web"} - - {include file="master2/site_navigation.tpl"/} - {/unless} - -{if condition="html"} - -
    -
    -
    -
    -{/if} - -
    -
    -
    - -
    - Edit Node Summary - -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    - -{if condition="html"} - -
    -
    -
    -{/if} - - -{if condition="html"} - - - - {include file="master2/optional_enhancement_js.tpl"/} - - - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/node_title.tpl b/examples/roc_api/site/www/template/html/modules/node_title.tpl deleted file mode 100644 index 2e02d02..0000000 --- a/examples/roc_api/site/www/template/html/modules/node_title.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{if condition="html"} - - - - {include file="master2/head.tpl"/} - - -{/if} - - {unless condition="$web"} - - {include file="master2/site_navigation.tpl"/} - {/unless} - - -{if condition="html"} - -
    -
    -
    -
    -{/if} - -
    -
    -
    - -
    - Edit Node Title - -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    -{if condition="html"} - -
    -
    -
    -{/if} - - -{if condition="html"} - - - - {include file="master2/optional_enhancement_js.tpl"/} - - - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/nodes.tpl b/examples/roc_api/site/www/template/html/modules/nodes.tpl deleted file mode 100644 index 23b24c7..0000000 --- a/examples/roc_api/site/www/template/html/modules/nodes.tpl +++ /dev/null @@ -1,52 +0,0 @@ -{if condition="html"} - - - - {include file="master2/head.tpl"/} - - -{/if} - -{unless condition="$web"} - - {include file="master2/site_navigation.tpl"/} -{/unless} - -{if condition="html"} - -
    -
    -
    -
    -{/if} -
    -

    List nodes


    - - - {foreach from="$nodes" item="item"} - - {/foreach} -
    - -{if condition="html"} -
    -
    -
    -{/if} - - -{if condition="html"} - - - - {include file="master2/optional_enhancement_js.tpl"/} - - - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/register.tpl b/examples/roc_api/site/www/template/html/modules/register.tpl deleted file mode 100644 index 3a14667..0000000 --- a/examples/roc_api/site/www/template/html/modules/register.tpl +++ /dev/null @@ -1,100 +0,0 @@ -{if condition="html"} - - - - {include file="master2/head.tpl"/} - - -{/if} - - -{unless condition="$web"} - - {include file="master2/site_navigation.tpl"/} -{/unless} - -{if condition="html"} - -
    -
    -
    -
    -{/if} - - -
    -
    -
    -
    - Register -
    -

    Register new user

    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - s
    - -
    - -
    -
    -
    -
    -
    - -{if condition="html"} -
    -
    -
    -{/if} - - -{if condition="html"} - - - - {include file="master2/optional_enhancement_js.tpl"/} - - - -{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/bootstrap/layout.tpl b/examples/roc_api/site/www/themes/bootstrap/layout.tpl deleted file mode 100644 index c2ed53f..0000000 --- a/examples/roc_api/site/www/themes/bootstrap/layout.tpl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - ROC- Layout with defualt Regions - - - - - - - - -ROC CMS - A responsive layout - - - - {include file="tpl/page_top.tpl"/} - - -
    - - - {include file="tpl/page_header.tpl"/} - - -
    - - - - {include file="tpl/left_sidebar.tpl"/} - - -
    - - {include file="tpl/highlighted_section.tpl"/} - - - - {include file="tpl/help_section.tpl"/} - - - - {include file="tpl/main_content.tpl"/} -
    - - - {include file="tpl/right_sidebar.tpl"/} -
    -
    - - - {include file="tpl/page_footer.tpl"/} - - - {include file="tpl/page_bottom.tpl"/} - - - - diff --git a/examples/roc_api/site/www/themes/bootstrap/page.tpl b/examples/roc_api/site/www/themes/bootstrap/page.tpl index 8ee484d..7f32495 100644 --- a/examples/roc_api/site/www/themes/bootstrap/page.tpl +++ b/examples/roc_api/site/www/themes/bootstrap/page.tpl @@ -4,12 +4,20 @@ ROC- Layout with defualt Regions - + + + + + + + + + + - @@ -17,13 +25,16 @@ - {$region_top/} - + {if isset="$top"} + {$region_top/} + {/if}
    - {$region_header/} +
    diff --git a/examples/roc_api/site/www/themes/bootstrap/roc_template -2.html b/examples/roc_api/site/www/themes/bootstrap/roc_template -2.html new file mode 100644 index 0000000..17b8074 --- /dev/null +++ b/examples/roc_api/site/www/themes/bootstrap/roc_template -2.html @@ -0,0 +1,108 @@ + + + + + ROC- Layout with defualt Regions + + + + + + + + +ROC CMS - A responsive layout + + + + +
    +

    ROC Layout with Defaul Regions

    + + + +
    + + + + + + + +
    +

    Highlighted Section

    +

    Help Section

    + +

    Main Content Section

    +

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.

    + +

    Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.

    +
    + + + +
    +
    + + + + + + + + + diff --git a/examples/roc_api/site/www/themes/bootstrap/roc_template.html b/examples/roc_api/site/www/themes/bootstrap/roc_template.html index 83d6149..1472f38 100644 --- a/examples/roc_api/site/www/themes/bootstrap/roc_template.html +++ b/examples/roc_api/site/www/themes/bootstrap/roc_template.html @@ -4,12 +4,20 @@ ROC- Layout with defualt Regions - + + + + + + + + + + - @@ -18,33 +26,72 @@ -
    -

    ROC Layout with Defaul Regions

    -