From a9bf9dabe35303601b9ddbc9642d9c7081e28f96 Mon Sep 17 00:00:00 2001 From: Daniel Quathamer Date: Wed, 26 Aug 2026 10:19:09 +0200 Subject: [PATCH] Initiales Datenmodell und JSP Viewer --- .classpath | 35 + .project | 17 + build.xml | 183 +++++ src-modules/module/portal/conf/excludes.txt | 10 + src-modules/module/portal/conf/includes.txt | 7 + src-modules/module/portal/conf/portal.xml | 642 ++++++++++++++++++ .../module/portal/masken/52000_felderinfo.unl | 7 + .../portal/masken/52000_maske_system_bez.unl | 1 + .../portal/masken/52000_masken_felder_bez.unl | 7 + .../module/portal/masken/52000_maskeninfo.unl | 62 ++ .../portal/masken/52000_sachgeb_maske_bez.unl | 1 + .../schluesseltabellen/fm_templates.unl | 337 +++++++++ .../fm_templates_fuellen.sql | 15 + .../schluesseltabellen/fm_templates_unload.x | 11 + .../schluesseltabellen/fm_templates_update.x | 17 + .../portal_config_fuellen_gang.sql | 64 ++ .../portal_config_fuellen_sample_superx.sql | 60 ++ .../portal_element_role.unl | 8 + .../portal_element_type.unl | 6 + .../portal_layout_fuellen.sql | 82 +++ src/de/superx/portal/PortalConfig.java | 123 ++++ src/de/superx/portal/PortalElement.java | 96 +++ .../conf/edustore/db/bin/SQL_ENV_portal.sam | 16 + .../lib/spring-context-indexer-6.2.19.jar | Bin 0 -> 27487 bytes superx/WEB-INF/lib/superx-portal.jar | Bin 0 -> 4320 bytes 25 files changed, 1807 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 build.xml create mode 100644 src-modules/module/portal/conf/excludes.txt create mode 100644 src-modules/module/portal/conf/includes.txt create mode 100644 src-modules/module/portal/conf/portal.xml create mode 100644 src-modules/module/portal/masken/52000_felderinfo.unl create mode 100644 src-modules/module/portal/masken/52000_maske_system_bez.unl create mode 100644 src-modules/module/portal/masken/52000_masken_felder_bez.unl create mode 100644 src-modules/module/portal/masken/52000_maskeninfo.unl create mode 100644 src-modules/module/portal/masken/52000_sachgeb_maske_bez.unl create mode 100644 src-modules/module/portal/schluesseltabellen/fm_templates.unl create mode 100644 src-modules/module/portal/schluesseltabellen/fm_templates_fuellen.sql create mode 100755 src-modules/module/portal/schluesseltabellen/fm_templates_unload.x create mode 100755 src-modules/module/portal/schluesseltabellen/fm_templates_update.x create mode 100644 src-modules/module/portal/schluesseltabellen/portal_config_fuellen_gang.sql create mode 100644 src-modules/module/portal/schluesseltabellen/portal_config_fuellen_sample_superx.sql create mode 100644 src-modules/module/portal/schluesseltabellen/portal_element_role.unl create mode 100644 src-modules/module/portal/schluesseltabellen/portal_element_type.unl create mode 100644 src-modules/module/portal/schluesseltabellen/portal_layout_fuellen.sql create mode 100644 src/de/superx/portal/PortalConfig.java create mode 100644 src/de/superx/portal/PortalElement.java create mode 100644 superx/WEB-INF/conf/edustore/db/bin/SQL_ENV_portal.sam create mode 100644 superx/WEB-INF/lib/spring-context-indexer-6.2.19.jar create mode 100644 superx/WEB-INF/lib/superx-portal.jar diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..703c23f --- /dev/null +++ b/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..14853ae --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + portal + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..231deb1 --- /dev/null +++ b/build.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src-modules/module/portal/conf/excludes.txt b/src-modules/module/portal/conf/excludes.txt new file mode 100644 index 0000000..3ab2249 --- /dev/null +++ b/src-modules/module/portal/conf/excludes.txt @@ -0,0 +1,10 @@ +rohdaten/ETL_ENV +rohdaten/*.properties +preparation.sql +finalize.sql +rohdaten/*.err +*.log +*.err +rohdaten/unl/* +conf/customize.sql +conf/*.log diff --git a/src-modules/module/portal/conf/includes.txt b/src-modules/module/portal/conf/includes.txt new file mode 100644 index 0000000..eec7122 --- /dev/null +++ b/src-modules/module/portal/conf/includes.txt @@ -0,0 +1,7 @@ +doku/etl_modul/etl.html +WEB-INF/conf/edustore/db/bin/SQL_ENV_etl.sam +WEB-INF/lib/superx-etl.jar +images/eye.svg +images/downloadblck.svg +images/resultset_up.svg + diff --git a/src-modules/module/portal/conf/portal.xml b/src-modules/module/portal/conf/portal.xml new file mode 100644 index 0000000..19e6b4e --- /dev/null +++ b/src-modules/module/portal/conf/portal.xml @@ -0,0 +1,642 @@ + + + + + + + + + + Schlüsseltabelle für Portalkonfigurationen + + + + + (optional) + + + (optional für Filterung) + + + + + +superx +superx +portal_config +tid +1 +portal_config_pk + + + + + + +
+ + + + + Portal-Tab Metadaten + + + + + + + + + bei Frames + bei Frames + bei DOM + + + + +superx +superx +portal_config_tab +tid +1 +portal_config_tab_pk + + + + + + +
+ + Portalkonfiguration-Menü Metadaten + + + + + + + + + +superx +superx +portal_config_menu +tid +1 +portal_config_menu_pk + + + + + + +
+ + Portal-Elemente + + + Maske, Wiki, static_html, dbform + + + JS-Hander, wenn auf das Element geklickt wird + + + + Bei Wiki und static_html + + + + + + + + + + + +superx +superx +portal_element +tid +1 +portal_element_pk + + + + + + +
+ + Schlüsseltabelle für Arten von Portalelementen + + + + + + + + + +superx +superx +portal_element_type +tid +1 +portal_element_type_pk + + + + + + +
+ + + Schlüsseltabelle für Rollen von Portalelementen + + + + + + + + + + +superx +superx +portal_element_role +tid +1 +portal_element_role_pk + + + + + + +
+ + Zuordnung Element zu Portal + + + + + + + Header,Footer,Sidebar-left, sidebar-right, content + + + Wert 1-32 (max) + in px + + + + +superx +superx +portal_config2element +tid +1 +portal_config2element_pk + + + + + + +
+ + + Portal-Layout + + + + + fixed (Feste Spalten), smart (Responsiv) + 1-32 + + + + + + +superx +superx +portal_layout +tid +1 +portal_layout_pk + + + +
+ + Zuordnung Layout zu Portal + + + + + optional + + + + +superx +superx +portal_config2layout +tid +1 +portal_config2layout_pk + + + + + + +
+ + + Verlinkung Portal-Menü zu Elementen + + + + + + + +superx +superx +portal_config_menu2element +tid +1 +portal_config_menu2element_pk + + + + + + +
+ + + + + + + + + + + + +Abfragen zur Administration von Portalkonfiguration + + + + + Portalkonfiguration verwalten + + $PORTAL_PFAD/masken + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+In diesem Formular können Sie Portale verwalten. Im Details-Formular können Sie Eigenschaften zuordnen. + + + + + + + + +
+In diesem Formular können Sie Layouts verwalten. + +tid + + + + + + + + + + + + + + + + + + +
+In diesem Formular können Sie Portal Layouts verwalten. Im Details-Formular können Sie Eigenschaften zuordnen. + + + + + + + + +
+In diesem Formular können Sie Layouts verwalten. + +tid + + + + + + + + + + + + + +
+In diesem Formular können Sie Elemente verwalten. + +tid + + + + + + + + + + + + +
+
+ diff --git a/src-modules/module/portal/masken/52000_felderinfo.unl b/src-modules/module/portal/masken/52000_felderinfo.unl new file mode 100644 index 0000000..dc4b18d --- /dev/null +++ b/src-modules/module/portal/masken/52000_felderinfo.unl @@ -0,0 +1,7 @@ +52000^Benutzer/in^50^0^0^150^200^1^integer^200^0^1^<> select tid,nvl(name,benutzer) from userinfo order by 2;^hidden^^ +52001^Portal-Layouts bearbeiten^1000^0^0^140^80^1^char^255^0^18^ ^ ^<> select '../edit/portal/portal_layout_list.jsp' from xdummy;^ +52003^Stichwort^20^0^0^150^150^1^sql^50^0^0^^^^ +52004^Komponente^1^0^0^150^200^1^integer^200^0^13^<> select tid,name from systeminfo order by 2;^ ^^ +52005^Portale bearbeiten^100^0^0^140^80^1^char^255^0^18^ ^ ^<> select '../edit/portal/portal_config_list.jsp' from xdummy;^ +52006^Virtuelle Tabelle^5^0^0^150^200^1^integer^200^0^13^<> select tid,caption from rpta_resultset where 1=1 /* and systeminfo_id=<> */ order by 2;^^^ +52008^Schlüssel^15^0^0^150^80^1^sql^200^0^0^ ^^^ diff --git a/src-modules/module/portal/masken/52000_maske_system_bez.unl b/src-modules/module/portal/masken/52000_maske_system_bez.unl new file mode 100644 index 0000000..3e33479 --- /dev/null +++ b/src-modules/module/portal/masken/52000_maske_system_bez.unl @@ -0,0 +1 @@ +52000^370^ diff --git a/src-modules/module/portal/masken/52000_masken_felder_bez.unl b/src-modules/module/portal/masken/52000_masken_felder_bez.unl new file mode 100644 index 0000000..1124436 --- /dev/null +++ b/src-modules/module/portal/masken/52000_masken_felder_bez.unl @@ -0,0 +1,7 @@ +52000^52000^ +52000^52001^ +52000^52003^ +52000^52004^ +52000^52005^ +52000^52006^ +52000^52008^ diff --git a/src-modules/module/portal/masken/52000_maskeninfo.unl b/src-modules/module/portal/masken/52000_maskeninfo.unl new file mode 100644 index 0000000..a012022 --- /dev/null +++ b/src-modules/module/portal/masken/52000_maskeninfo.unl @@ -0,0 +1,62 @@ +52000^Portale verwalten^--Autor: D. Quathamer\ +--Datum: 15.3.2024\ +--freemarker template\ +create temp table tmp_portal_config(\ + tid INTEGER , \ +uniquename VARCHAR(255) not null, \ +caption VARCHAR(255) , \ +userinfo_id INTEGER , \ +print_maskeninfo_id INTEGER , \ +booklet_stylesheet VARCHAR(255) ,\ +layout_uniquename varchar(255),\ +layout_id integer,\ +id_param_name VARCHAR(255) ,\ +nextedit varchar(255)\ +);\ +insert into tmp_portal_config (tid,\ + uniquename,\ + caption,\ + userinfo_id,\ + print_maskeninfo_id,\ + booklet_stylesheet,\ +-- id_param,\ +-- id_param_name,\ + nextedit) \ +select tid,\ + uniquename,\ + caption,\ + userinfo_id,\ + print_maskeninfo_id,\ + booklet_stylesheet,\ +-- id_param,\ +-- id_param_name\ + ('../edit/portal/portal_config_edit.jsp|tid=' || C.tid)::varchar(255)\ +FROM portal_config C\ +where 1=1\ +/* and C.caption ilike '%<>%' */\ +/* and C.uniquename ilike '%<>%' */\ +;\ +\ +\ +\ +select \ +caption,\ +uniquename,\ +nextedit \ +\ +from tmp_portal_config\ +order by caption ,uniquename\ +;^XIL List\ + drop_and_delete movable_columns sizable_columns horizontal_scrolling\ + white_space_color=COLOR_WHITE fixed_columns=2\ + min_heading_height=35\ +Column CID=0 heading_text="Name" center_heading\ + row_selectable col_selectable heading_platform readonly\ + width=50 text_size=100\ +Column CID=0 heading_text="Schlüssel" center_heading\ + row_selectable col_selectable heading_platform readonly\ + width=50 text_size=100\ +Column CID=1 heading_text="Bearbeiten" center_heading\ + row_selectable col_selectable heading_platform readonly\ + width=5 text_size=200\ +@@@^^^Portale und Inhalte verwalten.^drop table tmp_portal_config;^^1^440^360^0^1^ ^ diff --git a/src-modules/module/portal/masken/52000_sachgeb_maske_bez.unl b/src-modules/module/portal/masken/52000_sachgeb_maske_bez.unl new file mode 100644 index 0000000..61e91e2 --- /dev/null +++ b/src-modules/module/portal/masken/52000_sachgeb_maske_bez.unl @@ -0,0 +1 @@ +381^52000^ diff --git a/src-modules/module/portal/schluesseltabellen/fm_templates.unl b/src-modules/module/portal/schluesseltabellen/fm_templates.unl new file mode 100644 index 0000000..d99b9df --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/fm_templates.unl @@ -0,0 +1,337 @@ +222^PORTAL-Makros^<#macro PORTAL_FUELLEN portal_config portal_elements portal_tabs>\ + create temp table tmp_portal_config(\ + tid INTEGER , \ +uniquename VARCHAR(255) not null, \ +caption VARCHAR(255) , \ +userinfo_id INTEGER , \ +print_maskeninfo_id INTEGER , \ +booklet_stylesheet VARCHAR(255) ,\ +layout_uniquename varchar(255),\ +layout_id integer,\ +id_param_name VARCHAR(255) \ +\ +) \ +;\ +\ +create temp table tmp_portal_element(\ + tid INTEGER, \ + element_type_uniquename varchar(255),\ +element_type_id INTEGER , \ +caption VARCHAR(255) , \ +uniquename VARCHAR(255),\ +onclick_event VARCHAR(255) , \ +description VARCHAR(255) , \ +open_modal_card_detail SMALLINT default 1 , \ +src_url VARCHAR(255) , \ +content_static TEXT , \ +content_maskeninfo_id INTEGER , \ +content_chart_uniquename VARCHAR(255) , \ +content_rpta_column_layout_uniquename VARCHAR(255) , \ +content_tablestylesheet VARCHAR(255) , \ +link_maskeninfo_id INTEGER , \ +link_chart_uniquename VARCHAR(255) , \ +link_tablestylesheet VARCHAR(255) , \ +active SMALLINT default 1 not null\ +\ +) \ +;\ +\ +create temp table tmp_portal_config2element(\ + \ +portal_config_id INTEGER not null, \ +portal_element_id INTEGER not null, \ +portal_config_tab_id INTEGER , \ +sortnr INTEGER , \ +element_role_id INTEGER , \ +is_foldable INTEGER , \ +is_maximizable INTEGER , \ +min_width INTEGER , \ +height INTEGER , \ +active SMALLINT default 1 not null\ +) \ +;\ +\ +create temp table tmp_portal_config2layout(\ + \ +portal_config_id INTEGER not null, \ +portal_layout_id INTEGER not null, \ +userinfo_id INTEGER , \ +active SMALLINT default 1 not null\ +) \ +;\ +\ +create temp table tmp_portal_config_tab(\ + \ +portal_config_id INTEGER, \ +caption VARCHAR(255) , \ +print_maskeninfo_id INTEGER , \ +booklet_stylesheet VARCHAR(255) , \ +sortnr SMALLINT default 0 , \ +tab_id VARCHAR(255) , \ +target_url VARCHAR(255) , \ +target_window VARCHAR(255) , \ +target_div VARCHAR(255) \ +\ +) \ +;\ +\ +insert into tmp_portal_config(uniquename,\ + caption,\ +-- userinfo_id,\ + print_maskeninfo_id,\ + booklet_stylesheet,\ + id_param_name)\ +select '${portal_config.uniquename}',\ +'${portal_config.caption}',\ +<#if portal_config.print_maskeninfo_id?exists> ${portal_config.print_maskeninfo_id} <#else> null::integer,\ +<#if portal_config.booklet_stylesheet?exists> '${portal_config.booklet_stylesheet}' <#else> null::varchar(255) ,\ +<#if portal_config.id_param_name?exists> '${portal_config.id_param_name}' <#else> null::varchar(255) \ +from xdummy;\ +\ +update portal_config set caption='${portal_config.caption}'\ +<#if portal_config.print_maskeninfo_id?exists>, print_maskeninfo_id=${portal_config.print_maskeninfo_id} \ +<#if portal_config.booklet_stylesheet?exists>, booklet_stylesheet='${portal_config.booklet_stylesheet}' \ +<#if portal_config.id_param_name?exists>, id_param_name='${portal_config.id_param_name}' \ +where uniquename='${portal_config.uniquename}';\ +\ +delete from tmp_portal_config where uniquename in (select uniquename\ +from portal_config);\ +\ +insert into portal_config(uniquename,\ + caption,\ +-- userinfo_id,\ + print_maskeninfo_id,\ + booklet_stylesheet,\ + id_param_name)\ + select uniquename,\ + caption,\ +-- userinfo_id,\ + print_maskeninfo_id,\ + booklet_stylesheet,\ + id_param_name\ + from tmp_portal_config;\ + \ +\ +--Zuordnung zu Layout:\ +\ +insert into tmp_portal_config2layout(portal_config_id,\ + portal_layout_id,\ + userinfo_id,\ + active)\ + select C.tid,\ + L.tid as layout_id,\ + null::integer,\ + 1 as active\ + from portal_config C, portal_layout L\ + where L.uniquename='${portal_config.layout_uniquename}'\ + and C.uniquename='${portal_config.uniquename}';\ +\ +delete from portal_config2layout\ +where (portal_config_id,portal_layout_id) in (\ +select portal_config_id,portal_layout_id\ +from tmp_portal_config2layout);\ +\ +insert into portal_config2layout(portal_config_id,\ + portal_layout_id,\ + userinfo_id,\ + active)\ + select portal_config_id,\ + portal_layout_id,\ + userinfo_id,\ + active\ + from tmp_portal_config2layout;\ + \ + \ +<#foreach elem in portal_elements>\ +insert into tmp_portal_element(\ +element_type_id,\ + caption,\ + uniquename,\ + onclick_event,\ + description,\ + open_modal_card_detail,\ + src_url,\ + content_static,\ + content_maskeninfo_id,\ + content_chart_uniquename,\ + content_rpta_column_layout_uniquename,\ + content_tablestylesheet,\ + link_maskeninfo_id,\ + link_chart_uniquename,\ + link_tablestylesheet,\ + active)\ +select T.tid,\ +'${elem.caption}',\ +'${elem.uniquename}',\ +<#if elem.onclick_event?exists> '${elem.onclick_event}' <#else> null::varchar(255),\ +<#if elem.description?exists> '${elem.description}' <#else> null::varchar(255),\ +<#if elem.open_modal_card_detail?exists> 1 <#else> 0,\ +<#if elem.src_url?exists> '${elem.src_url}' <#else> null::varchar(255),\ +<#if elem.content_static?exists> '${elem.content_static?replace("'","''")}' <#else> null::varchar(255),\ +<#if elem.content_maskeninfo_id?exists> ${elem.content_maskeninfo_id} <#else> null::integer,\ +<#if elem.content_chart_uniquename?exists> '${elem.content_chart_uniquename}' <#else> null::varchar(255),\ +<#if elem.content_rpta_column_layout_uniquename?exists> '${elem.content_rpta_column_layout_uniquename}' <#else> null::varchar(255),\ +<#if elem.content_tablestylesheet?exists> '${elem.content_tablestylesheet}' <#else> null::varchar(255),\ +<#if elem.link_maskeninfo_id?exists> link_maskeninfo_id <#else> null::integer,\ +<#if elem.link_chart_uniquename?exists> '${elem.link_chart_uniquename}' <#else> null::varchar(255),\ +<#if elem.link_tablestylesheet?exists> '${elem.link_tablestylesheet}' <#else> null::varchar(255),\ +1 as active\ +from portal_element_type T\ +where T.uniquename= '${elem.element_type}';\ +\ +\ +\ +\ +update portal_element E set caption=T.caption,\ +element_type_id=T.element_type_id,\ + onclick_event=T.onclick_event,\ + description=T.description,\ + open_modal_card_detail=T.open_modal_card_detail,\ + src_url=T.src_url,\ + content_static=T.content_static,\ + content_maskeninfo_id=T.content_maskeninfo_id,\ + content_chart_uniquename=T.content_chart_uniquename,\ + content_rpta_column_layout_uniquename=T.content_rpta_column_layout_uniquename,\ + content_tablestylesheet=T.content_tablestylesheet,\ + link_maskeninfo_id=T.link_maskeninfo_id,\ + link_chart_uniquename=T.link_chart_uniquename,\ + link_tablestylesheet=T.link_tablestylesheet,\ + active=T.active\ +from tmp_portal_element T\ + where T.uniquename=E.uniquename\ + and E.uniquename in (select T2.uniquename from tmp_portal_element T2);\ +\ +delete from tmp_portal_element where uniquename in (select uniquename\ +from portal_element);\ +\ +insert into portal_element(\ +element_type_id,\ + caption,\ + uniquename,\ + onclick_event,\ + description,\ + open_modal_card_detail,\ + src_url,\ + content_static,\ + content_maskeninfo_id,\ + content_chart_uniquename,\ + content_rpta_column_layout_uniquename,\ + content_tablestylesheet,\ + link_maskeninfo_id,\ + link_chart_uniquename,\ + link_tablestylesheet,\ + active)\ + select element_type_id,\ + caption,\ + uniquename,\ + onclick_event,\ + description,\ + open_modal_card_detail,\ + src_url,\ + content_static,\ + content_maskeninfo_id,\ + content_chart_uniquename,\ + content_rpta_column_layout_uniquename,\ + content_tablestylesheet,\ + link_maskeninfo_id,\ + link_chart_uniquename,\ + link_tablestylesheet,\ + active\ + from tmp_portal_element;\ +\ + \ + delete from portal_config2element where \ + portal_config_id =(select T.tid from portal_config T where T.uniquename='${portal_config.uniquename}');\ +\ + <#assign sortnr=0 />\ +<#foreach elem in portal_elements>\ + <#assign sortnr=sortnr +1 />\ + \ + insert into portal_config2element(\ + portal_config_id,\ + portal_element_id,\ + --portal_config_tab_id,\ + sortnr,\ + element_role_id,\ + is_foldable,\ + is_maximizable,\ + min_width,\ + height,\ + active)\ +select T.tid as portal_config_id,\ + E.tid as portal_element_id,\ + --portal_config_tab_id,\ + ${sortnr} as sortnr,\ + R.tid as element_role_id,\ + <#if elem.is_foldable?exists> 1 <#else> 0 as is_foldable,\ + <#if elem.is_maximizable?exists> 1 <#else> 0 as is_maximizable,\ + <#if elem.min_width?exists> ${elem.min_width} <#else> null::integer as min_width,\ + <#if elem.height?exists> ${elem.height} <#else> null::integer as height,\ + 1 as active\ + from portal_config T, portal_element_role R, portal_element E\ + where T.uniquename='${portal_config.uniquename}'\ + and R.uniquename='${elem.element_role}'\ + and E.uniquename='${elem.uniquename}';\ + \ +\ +\ +--TABS:\ +<#assign sortnr=0 />\ +\ +<#foreach elem in portal_tabs>\ +<#assign sortnr=sortnr+1 />\ +insert into tmp_portal_config_tab(\ +portal_config_id,\ + caption,\ +-- print_maskeninfo_id,\ +-- booklet_stylesheet,\ + sortnr,\ + tab_id,\ + target_url,\ + target_window,\ + target_div)\ +select T.tid,\ +'${elem.caption}',\ +${sortnr},\ +'${elem.tab_id}',\ +<#if elem.target_url?exists> '${elem.target_url}' <#else> null::varchar(255),\ +<#if portal_config.tab_target_window?exists> '${portal_config.tab_target_window}' <#else> null::varchar(255),\ +<#if portal_config.target_div?exists> '${portal_config.target_div}' <#else> null::varchar(255)\ +\ +from portal_config T\ +where T.uniquename= '${portal_config.uniquename}';\ +\ +\ +\ +\ +delete from portal_config_tab where \ + portal_config_id =(select T.tid from portal_config T where T.uniquename='${portal_config.uniquename}');\ +\ + insert into portal_config_tab(\ +portal_config_id,\ + caption,\ +-- print_maskeninfo_id,\ +-- booklet_stylesheet,\ + sortnr,\ + tab_id,\ + target_url,\ + target_window,\ + target_div)\ + select portal_config_id,\ + caption,\ +-- print_maskeninfo_id,\ +-- booklet_stylesheet,\ + sortnr,\ + tab_id,\ + target_url,\ + target_window,\ + target_div\ + from tmp_portal_config_tab;\ + \ +\ +drop table tmp_portal_config;\ +drop table tmp_portal_element;\ +drop table tmp_portal_config2element;\ +drop table tmp_portal_config2layout;\ +drop table tmp_portal_config_tab;\ + ^Makros des Portal-Moduls^^1^ diff --git a/src-modules/module/portal/schluesseltabellen/fm_templates_fuellen.sql b/src-modules/module/portal/schluesseltabellen/fm_templates_fuellen.sql new file mode 100644 index 0000000..17b375a --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/fm_templates_fuellen.sql @@ -0,0 +1,15 @@ + +delete from fm_templates where id in (select id from tmp_templates); + +insert into fm_templates(id, + content, + description, + comment, + version) select id, + content, + description, + comment, + version from tmp_templates; + +drop table tmp_templates; + diff --git a/src-modules/module/portal/schluesseltabellen/fm_templates_unload.x b/src-modules/module/portal/schluesseltabellen/fm_templates_unload.x new file mode 100755 index 0000000..5d4eb2b --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/fm_templates_unload.x @@ -0,0 +1,11 @@ +#!/bin/bash +#löscht alle nicht-kern-templates und entlädt die Tabelle sortiert ins Rohdaten Verzeichnis (für git-diff). + + + + +SX_CLIENT=jdbc +export SX_CLIENT +#man_catalogue +DOQUERY "select * from fm_templates where id in ('PORTAL-Makros')" false $DBDELIMITER ./fm_templates.unl txt + diff --git a/src-modules/module/portal/schluesseltabellen/fm_templates_update.x b/src-modules/module/portal/schluesseltabellen/fm_templates_update.x new file mode 100755 index 0000000..e2bc6db --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/fm_templates_update.x @@ -0,0 +1,17 @@ +#!/bin/bash + +DOQUERY "create table tmp_templates(tid integer, + id char(200) not null, +content text not null, +description char(200) , +comment char(200) , +version integer default 1 + +) +;" + +sx_auto_upload_table.x tmp_templates ./fm_templates.unl + +DOSQL fm_templates_fuellen.sql + + diff --git a/src-modules/module/portal/schluesseltabellen/portal_config_fuellen_gang.sql b/src-modules/module/portal/schluesseltabellen/portal_config_fuellen_gang.sql new file mode 100644 index 0000000..cfb2965 --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/portal_config_fuellen_gang.sql @@ -0,0 +1,64 @@ +--freemarker template +<#include "PORTAL-Makros"/> + +<#assign portal_config = +{"uniquename":"portal_config_gang_bearbeiten", +"caption":"Studiengang bearbeiten", +"print_maskeninfo_id":"25100", +"layout_uniquename":"COLUMNS_2", +"id_param_name":"tid", +"tab_target_window":"parent.editPane"} + /> + + +<#assign portal_elements = [ +{"element_type":"STATIC_HTML", "caption":"GANG Kopfzeile", +"uniquename":"GANG_HEADER", "src_url":"", + "content_static":"GANG Studiengangsverwaltung", + "element_role":"HEADER"}, + {"element_type":"STATIC_HTML", "caption":"GANG Menue", +"uniquename":"GANG_MENU", "src_url":"../../edit/gang/menue.jsp", + "content_static":"menü", + "element_role":"CONTENT", + "min_width":"4", + "height":"400"}, + {"element_type":"IFRAME", "caption":"GANG Content", +"uniquename":"GANG_CONTENT", "src_url":"../../edit/gang/studiengang_edit.jsp", + "content_static":"Inhalt", + "element_role":"CONTENT", + "min_width":"8", + "height":"400"}, +{"element_type":"STATIC_HTML", "caption":"GANG Fusszeile", +"uniquename":"SX_FOOTER", "src_url":"../../edit/gang/bottombar.htm", +"content_static":" +", + "element_role":"FOOTER"} +] /> + + +<#assign portal_tabs = [ +{"caption":"Studiengang", "tab_id":"Linkstudiengang", "target_url":"../../edit/gang/studiengang_edit.jsp"}, +{"caption":"Zuordnung", "tab_id":"Linkzuordnung", "target_url":"../../edit/gang/zuordnung_edit.jsp"}, +{"caption":"Allgemein", "tab_id":"Linkallgemein", "target_url":"../../edit/gang/allgemein_edit.jsp"}, +{"caption":"Bes. Studienform", "tab_id":"Linkstudienformen", "target_url":"../../edit/gang/studienformen_edit.jsp"}, +{"caption":"Zulassung", "tab_id":"Linkzulassung", "target_url":"../../edit/gang/zulassung_edit.jsp"}, +{"caption":"Zulassungszahlen", "tab_id":"Linkzulassungszahlen", "target_url":"../../edit/gang/zulassungszahlen_edit.jsp"}, +{"caption":"Kapazität", "tab_id":"Linkkapazitaet", "target_url":"../../edit/gang/kapazitaet_edit.jsp"}, +{"caption":"Prüfungsrechtliches", "tab_id":"Linkpruefung", "target_url":"../../edit/gang/pruefung_edit.jsp"}, +{"caption":"Initialisierung", "tab_id":"Linkinitialisierung", "target_url":"../../edit/gang/initialisierung_edit.jsp"}, +{"caption":"Akkreditierung", "tab_id":"Linkakkreditierung", "target_url":"../../edit/gang/akkreditierung_edit.jsp"}, +{"caption":"Qualitätssicherung", "tab_id":"Linkevaluation", "target_url":"../../edit/gang/studiengang_edit.jsp"}, +{"caption":"Einstellung", "tab_id":"Linkabwicklung", "target_url":"../../edit/gang/abwicklung_edit.jsp"} +] /> + +<@PORTAL_FUELLEN portal_config=portal_config portal_elements=portal_elements portal_tabs=portal_tabs /> + + + + + diff --git a/src-modules/module/portal/schluesseltabellen/portal_config_fuellen_sample_superx.sql b/src-modules/module/portal/schluesseltabellen/portal_config_fuellen_sample_superx.sql new file mode 100644 index 0000000..dc611ad --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/portal_config_fuellen_sample_superx.sql @@ -0,0 +1,60 @@ +--freemarker template +<#include "PORTAL-Makros"/> + +<#assign portal_config = +{"uniquename":"portal_config_sample_superx", +"caption":"SuperX-Beispielportal", +"print_maskeninfo_id":"25100", +"layout_uniquename":"SUPERX_CARD", +"id_param_name":"", +"tab_target_window":""} + /> + + +<#assign portal_elements = [ +{"element_type":"STATIC_HTML", "caption":"SuperX Kopfzeile", +"uniquename":"SX_HEADER", "src_url":"", + "content_static":"SuperX-Beispielportal Header", + "element_role":"HEADER", + "min_width":"100", + "height":"40"}, +{"element_type":"STATIC_HTML", "caption":"SuperX Content Beispielinhalt", +"uniquename":"SX_CONTENT1", "src_url":"", + "content_static":"Dieses Portal", + "element_role":"CONTENT", + "min_width":"33", + "height":"60"}, +{"element_type":"STATIC_HTML", "caption":"SuperX Content Beispielinhalt 2", +"uniquename":"SX_CONTENT2", "src_url":"", + "content_static":"ist nur", + "element_role":"CONTENT", + "min_width":"33", + "height":"60"}, +{"element_type":"STATIC_HTML", "caption":"SuperX Content Beispielinhalt 3", +"uniquename":"SX_CONTENT3", "src_url":"", + "content_static":"ein Muster", + "element_role":"CONTENT", + "min_width":"33", + "height":"60"}, +{"element_type":"STATIC_HTML", "caption":"SuperX Fusszeile", +"uniquename":"SX_FOOTER", +"content_static":" +", + "element_role":"FOOTER", + "min_width":"100", + "height":"40"} +] /> + + +<#assign portal_tabs = [ +] /> + +<@PORTAL_FUELLEN portal_config=portal_config portal_elements=portal_elements portal_tabs=portal_tabs /> + + + diff --git a/src-modules/module/portal/schluesseltabellen/portal_element_role.unl b/src-modules/module/portal/schluesseltabellen/portal_element_role.unl new file mode 100644 index 0000000..1b52fe9 --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/portal_element_role.unl @@ -0,0 +1,8 @@ +1^CONTENT^Inhalt^1^ +2^FOOTER^Fusszeile^0^ +3^HEADER^Kopfzeile^0^ +4^TAB_BOTTOM^Reiter (unten)^0^ +5^TAB_TOP^Reiter (oben)^0^ +6^SIDEBAR_LEFT^Sidebar-links^0^ +7^SIDEBAR_RIGHT^Sidebar-rechts^0^ +8^MENU^Menüzeile^1^ diff --git a/src-modules/module/portal/schluesseltabellen/portal_element_type.unl b/src-modules/module/portal/schluesseltabellen/portal_element_type.unl new file mode 100644 index 0000000..002a3e7 --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/portal_element_type.unl @@ -0,0 +1,6 @@ +1^STATIC_HTML^Statisches HTML^ +2^STATIC_WIKI^Statisches Wiki^ +3^MASKE^Maske^ +4^DBFORM^DB-Form^ +5^VIZ_CHART^VIZ-Grafik^ +6^IFRAME^Inline-Frame^ diff --git a/src-modules/module/portal/schluesseltabellen/portal_layout_fuellen.sql b/src-modules/module/portal/schluesseltabellen/portal_layout_fuellen.sql new file mode 100644 index 0000000..fdf631b --- /dev/null +++ b/src-modules/module/portal/schluesseltabellen/portal_layout_fuellen.sql @@ -0,0 +1,82 @@ +--freemarker template +<#assign portal_layouts = [ +{"uniquename":"FRAMESET_GANG", +"caption":"GANG-Portal mit Frame-Layout"}, +{"uniquename":"CARD_V", +"caption":"Cards (vertikal)"}, +{"uniquename":"FLEXBOX_GRID_3COLS", +"caption":"Flexbox-Grid (dreispaltig)", +"fixed_grid_column_count","3"}, +{"uniquename":"FLEXBOX_GRID_2COLS", +"caption":"Flexbox-Grid (zweispaltig)", +"fixed_grid_column_count","2"}, +{"uniquename":"FLEXBOX_GRID", +"caption":"Flexbox-Grid (responsiv)"}, +{"uniquename":"COLUMNS_2", +"caption":"Inhalt zweispaltig", +"fixed_grid_column_count","2"} + +] + /> + + create temp table tmp_portal_layout( + tid SERIAL not null, +caption VARCHAR(255) , +uniquename VARCHAR(255) , +grid_type VARCHAR(255) , +fixed_grid_column_count SMALLINT, +css_url VARCHAR(255) , +js_url VARCHAR(255) , +onload_handler VARCHAR(255) +) +; +<#foreach elem in portal_layouts> +insert into tmp_portal_layout(caption, + uniquename, + grid_type, + fixed_grid_column_count, + css_url, + js_url, + onload_handler) + select + '${elem.caption}', +'${elem.uniquename}', +<#if elem.grid_type?exists> '${elem.grid_type}' <#else> null::varchar(255), +<#if elem.fixed_grid_column_count?exists> ${elem.fixed_grid_column_count} <#else> null::integer, +<#if elem.css_url?exists> '${elem.css_url}' <#else> null::varchar(255), +<#if elem.js_url?exists> '${elem.js_url}' <#else> null::varchar(255), +<#if elem.onload_handler?exists> '${elem.onload_handler}' <#else> null::varchar(255) +from xdummy; + + + +update portal_layout L set caption=T.caption, +grid_type=T.grid_type, + fixed_grid_column_count=T.fixed_grid_column_count, + css_url=T.css_url, + js_url=T.js_url, + onload_handler=T.onload_handler +from tmp_portal_layout T + where L.uniquename in (select T2.uniquename from tmp_portal_layout T2); + +delete from tmp_portal_layout where uniquename in (select uniquename +from portal_layout); + +insert into portal_layout(caption, + uniquename, + grid_type, + fixed_grid_column_count, + css_url, + js_url, + onload_handler) + select caption, + uniquename, + grid_type, + fixed_grid_column_count, + css_url, + js_url, + onload_handler +from tmp_portal_layout; + +drop table tmp_portal_layout; + diff --git a/src/de/superx/portal/PortalConfig.java b/src/de/superx/portal/PortalConfig.java new file mode 100644 index 0000000..1ee36a6 --- /dev/null +++ b/src/de/superx/portal/PortalConfig.java @@ -0,0 +1,123 @@ +package de.superx.portal; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.LinkedList; +import java.util.List; + +public class PortalConfig { + public PortalConfig(String uniquename) { + super(); + this.uniquename = uniquename; + } + List elementList = new LinkedList(); + + String uniquename; + int configTid; + String configCaption; + String idParamName; + String layoutUniquename; + public String PortalElementsSql; + public String PortalConfigSql; + + public int getConfigTid() { + return configTid; + } + public void setConfigTid(int configTid) { + this.configTid = configTid; + } + public String getConfigCaption() { + return configCaption; + } + public void setConfigCaption(String configCaption) { + this.configCaption = configCaption; + } + public String getIdParamName() { + return idParamName; + } + public void setIdParamName(String idParamName) { + this.idParamName = idParamName; + } + public String getLayoutUniquename() { + return layoutUniquename; + } + public void setLayoutUniquename(String layoutUniquename) { + this.layoutUniquename = layoutUniquename; + } + public String getPortalConfigSql() { + return PortalConfigSql; + } + public void setPortalConfigSql(String portletLayoutUniquename ) { + String sql="select C.tid as config_tid,C.caption as config_caption,C.id_param_name,L.uniquename as layout_uniquename"; + sql+=" from portal_config C, portal_config2layout CL, portal_layout L"; + sql+=" where C.uniquename='"+this.uniquename+"'"; + sql+=" and C.tid=CL.portal_config_id and L.tid=CL.portal_layout_id"; + sql+= " and L.uniquename='"+portletLayoutUniquename+"'"; + + PortalConfigSql = sql; + } + public void setPortalConfigAttributesFromSQL(ResultSet rs) throws SQLException + { + while (rs.next()) + { + if(rs.getObject(1) !=null) + { + configTid=(int) rs.getObject(1); + configCaption=rs.getString(2); + idParamName=rs.getString(3); + layoutUniquename=rs.getString(4); + } + } + } + public String getPortalElementsSql() { + String sql="select T.uniquename as element_type_uniquename,R.uniquename as element_role_uniquename,"; + sql+="E.content_static,E.src_url,"; + sql+="E.caption as element_caption,E.uniquename as element_uniquename,"; + sql+= "EC.tid as portal_element2config_tid,"; + sql+= "EC.min_width,EC.height,EC.sortnr,EC.is_foldable,EC.is_maximizable"; + sql+=" from portal_element_type T, portal_config2element EC, portal_config C,portal_element_role R, portal_element E"; + sql+=" where T.tid=E.element_type_id and C.tid=EC.portal_config_id and R.tid=EC.element_role_id "; + sql+=" and E.tid=EC.portal_element_id"; + sql+=" and E.active=1 and EC.active=1"; + sql+=" and C.uniquename='"+this.uniquename+"'"; + sql+=" order by EC.sortnr,E.caption"; + return sql; + } + public void setPortalConfigElementsFromSQL(ResultSet rs) throws SQLException + { + while (rs.next()) + { + if(rs.getObject(1) !=null && rs.getObject(1) != null) + { + PortalElement myElem=new PortalElement(rs.getString(6)); + myElem.setElementTypeUniquename(rs.getString(1)); + myElem.setElementRoleUniquename(rs.getString(2)); + myElem.setContentStatic(rs.getString(3)); + myElem.setSrcUrl(rs.getString(4)); + myElem.setElementCaption(rs.getString(5)); + myElem.setMinWidth(getIntFromRs(rs.getObject(8),100)); + myElem.setHeight(getIntFromRs(rs.getObject(9),80)); + myElem.setSortnr(getIntFromRs(rs.getObject(10),0)); + myElem.setFoldable( (rs.getObject(11)==null || getIntFromRs(rs.getObject(11),0)==0 ?false:true)); + myElem.setIs_maximizable( (rs.getObject(12)==null || getIntFromRs(rs.getObject(12),0)==0 ?false:true)); + + elementList.add(myElem); + } + } + } + public List getElementList() + { + return elementList; + } + public static int getIntFromRs(Object o,int defaultWert) + { + int ret=defaultWert; + if(o!=null && o instanceof Integer) + { + ret=(int) o; + } + + return ret; + } + +} diff --git a/src/de/superx/portal/PortalElement.java b/src/de/superx/portal/PortalElement.java new file mode 100644 index 0000000..cc22e2a --- /dev/null +++ b/src/de/superx/portal/PortalElement.java @@ -0,0 +1,96 @@ +package de.superx.portal; + +public class PortalElement { + public PortalElement(String elementUniquename) { + super(); + this.elementUniquename = elementUniquename; + } + String elementRoleUniquename; + String elementCaption; + String elementUniquename; + String contentStatic; + String srcUrl; + int portalElement2configTid; + int minWidth; + int height; + int sortnr; + boolean isFoldable; + boolean is_maximizable; + String elementTypeUniquename; + + public String getElementTypeUniquename() { + return elementTypeUniquename; + } + public void setElementTypeUniquename(String elementTypeUniquename) { + this.elementTypeUniquename = elementTypeUniquename; + } + public String getElementRoleUniquename() { + return elementRoleUniquename; + } + public void setElementRoleUniquename(String elementRoleUniquename) { + this.elementRoleUniquename = elementRoleUniquename; + } + public String getElementCaption() { + return elementCaption; + } + public void setElementCaption(String elementCaption) { + this.elementCaption = elementCaption; + } + public String getElementUniquename() { + return elementUniquename; + } + public void setElementUniquename(String elementUniquename) { + this.elementUniquename = elementUniquename; + } + public String getContentStatic() { + return contentStatic; + } + public void setContentStatic(String contentStatic) { + this.contentStatic = contentStatic; + } + public String getSrcUrl() { + return srcUrl; + } + public void setSrcUrl(String srcUrl) { + this.srcUrl = srcUrl; + } + public int getPortalElement2configTid() { + return portalElement2configTid; + } + public void setPortalElement2configTid(int portalElement2configTid) { + this.portalElement2configTid = portalElement2configTid; + } + public int getMinWidth() { + return minWidth; + } + public void setMinWidth(int minWidth) { + this.minWidth = minWidth; + } + public int getHeight() { + return height; + } + public void setHeight(int height) { + this.height = height; + } + public int getSortnr() { + return sortnr; + } + public void setSortnr(int sortnr) { + this.sortnr = sortnr; + } + public boolean isFoldable() { + return isFoldable; + } + public void setFoldable(boolean isFoldable) { + this.isFoldable = isFoldable; + } + public boolean isMaximizable() { + return is_maximizable; + } + public void setIs_maximizable(boolean is_maximizable) { + this.is_maximizable = is_maximizable; + } + + + +} diff --git a/superx/WEB-INF/conf/edustore/db/bin/SQL_ENV_portal.sam b/superx/WEB-INF/conf/edustore/db/bin/SQL_ENV_portal.sam new file mode 100644 index 0000000..334e36e --- /dev/null +++ b/superx/WEB-INF/conf/edustore/db/bin/SQL_ENV_portal.sam @@ -0,0 +1,16 @@ +#Beispielumgebung für das PORTAL-Modul: + +#SUPERX_MODULE=$SUPERX_DIR/db/module +#SUPERX_ROHDATEN=rohdaten + +PORTAL_PFAD=$SUPERX_MODULE/portal; export PORTAL_PFAD +PORTAL_ERRORDAT=$PORTAL_PFAD/portal_update.err; export PORTAL_ERRORDAT +#Hier stehen die Rohdaten (im Unterverzeichnis unl) +PORTAL_LOAD_PFAD=$PORTAL_PFAD/$SUPERX_ROHDATEN; export PORTAL_LOAD_PFAD +PORTAL_ERRORMAIL=$ERRORMAIL; export PORTAL_ERRORMAIL +PORTAL_LOGMAIL=$LOGMAIL; export PORTAL_LOGMAIL + +PATH=$PORTAL_PFAD/bin:$PATH +export PATH + + diff --git a/superx/WEB-INF/lib/spring-context-indexer-6.2.19.jar b/superx/WEB-INF/lib/spring-context-indexer-6.2.19.jar new file mode 100644 index 0000000000000000000000000000000000000000..6b2bbdcc2eebd3168b05f4a89060ad825728bcfe GIT binary patch literal 27487 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 literal 0 HcmV?d00001 diff --git a/superx/WEB-INF/lib/superx-portal.jar b/superx/WEB-INF/lib/superx-portal.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb742420ba50fcb69da752be813a8e87535b7e5c GIT binary patch literal 4320 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 AXaE2J literal 0 HcmV?d00001