一種通過(guò)xml動(dòng)態(tài)配置網(wǎng)站的方法【專利說(shuō)明】所屬
技術(shù)領(lǐng)域:
[0001]本發(fā)明涉及一種通過(guò)XML動(dòng)態(tài)配置網(wǎng)站的方法?!?br>背景技術(shù):
】[0002]XMAP是一個(gè)能把XML映射到Java對(duì)象的類庫(kù),通過(guò)對(duì)XML中的各標(biāo)簽進(jìn)行遍歷解析,將解析的值放入聲明好的java對(duì)象中,這樣一來(lái)可以通過(guò)XML配置java對(duì)象,達(dá)到模塊化的效果,但解析的過(guò)程很麻煩,需要復(fù)雜的代碼來(lái)實(shí)現(xiàn)對(duì)每個(gè)java對(duì)象的映射,不適于新手來(lái)操作?!?br/>發(fā)明內(nèi)容】[0003]為了克服現(xiàn)有的XMAP類庫(kù)不易于操作的不足,本發(fā)明提供了一套完整的解析器,涵蓋了一個(gè)網(wǎng)站所必需的各個(gè)組成部件(如布局、插件),用戶可以通過(guò)擴(kuò)展的方式迅速定位到一個(gè)部件的解析器并方便地配置該部件。[0004]本發(fā)明解決其技術(shù)問(wèn)題所采用的技術(shù)方案是:在XML文件中通過(guò)擴(kuò)展標(biāo)簽〈extens1n〉來(lái)定義部件,擴(kuò)展標(biāo)簽包含一個(gè)擴(kuò)展目標(biāo)屬性用于指明在頁(yè)面中加載該類部件的方法類,以及一個(gè)擴(kuò)展點(diǎn)屬性用于指明解析該部件XML內(nèi)容的解析器,用戶可以在擴(kuò)展標(biāo)簽中對(duì)部件進(jìn)行配置(如設(shè)置插件的顯示內(nèi)容)或組裝(如在布局中插入插件),系統(tǒng)啟動(dòng)時(shí)會(huì)通過(guò)擴(kuò)展點(diǎn)獲取解析該部件的解析器并將該部件的XML內(nèi)容映射成一個(gè)java對(duì)象,頁(yè)面調(diào)用時(shí)會(huì)通過(guò)擴(kuò)展目標(biāo)計(jì)算該java對(duì)象(根據(jù)運(yùn)行環(huán)境判斷是否顯示該部件以及根據(jù)部件屬性生成前臺(tái)樣式)生成網(wǎng)頁(yè)組件,從而使得用戶可以通過(guò)XML方便地配置網(wǎng)站。[0005]本發(fā)明的有益效果是,可以讓沒(méi)有編程經(jīng)驗(yàn)的人僅通過(guò)xml就能深入地定制產(chǎn)品,包括數(shù)據(jù)架構(gòu)和文檔類型,表單,生命周期,監(jiān)聽(tīng)器,網(wǎng)頁(yè)用戶界面(按鈕、選項(xiàng)卡、鏈接、視圖、主題),工作流。【附圖說(shuō)明】[0006]圖1是本發(fā)明的XML配置數(shù)據(jù)架構(gòu)、文檔類型示意圖[0007]圖2是本發(fā)明的XML配置目錄示意圖[0008]圖3是本發(fā)明的XML載入目錄示意圖[0009]圖4是本發(fā)明的XML注冊(cè)插件類型示意圖[0010]圖5是本發(fā)明的XML實(shí)例化插件示意圖[0011]圖6是本發(fā)明的暴露插件變量示意圖[0012]圖7是本發(fā)明的插件調(diào)用前臺(tái)模板示意圖[0013]圖8是本發(fā)明的目錄生成詞匯樹(shù)示意圖[0014]圖9是本發(fā)明的下拉列表顯示詞匯樹(shù)示意圖[0015]圖10是本發(fā)明的提取XML中的擴(kuò)展框架示意圖[0016]圖11是本發(fā)明的根據(jù)依賴條件掛起、加載擴(kuò)展框架示意圖[0017]圖12是本發(fā)明的通過(guò)XML配置信息將擴(kuò)展框架填充完整示意圖[0018]圖13是本發(fā)明的通過(guò)XML配置信息操作插件示意圖[0019]圖14是本發(fā)明的注冊(cè)布局示意圖[0020]圖15是本發(fā)明的提取布局示意圖[0021]圖16是本發(fā)明的實(shí)現(xiàn)布局示意圖[0022]圖17是本發(fā)明的通過(guò)屬性配置布局行示意圖[0023]圖18是本發(fā)明的通過(guò)變量映射控制插件模式示意圖[0024]圖19是本發(fā)明的通過(guò)功能映射控制插件模式示意圖[0025]圖20是本發(fā)明的通過(guò)插件模式重用布局示意圖[0026]圖21是本發(fā)明的通過(guò)標(biāo)記功能測(cè)試方法示意圖[0027]圖22是本發(fā)明的通過(guò)插件模式重用插件示意圖[0028]圖23是本發(fā)明的XML定制網(wǎng)站綜述示意圖【具體實(shí)施方式】[0029]如圖1所示,系統(tǒng)啟動(dòng)時(shí)會(huì)將圖1左側(cè)的xml標(biāo)簽語(yǔ)言翻譯成圖1右側(cè)的數(shù)據(jù)架構(gòu)和文檔類型,圖1中部的代碼會(huì)對(duì)讀取的擴(kuò)展(extens1n)進(jìn)行判斷:[0030]當(dāng)擴(kuò)展點(diǎn)(point)為文檔類型(doctype)1-1且其標(biāo)簽為文檔類型(doctype)1-2時(shí),會(huì)用文檔類型描述符(DocumentTypeDescriptor)1-3實(shí)例化一個(gè)文檔類型,該例實(shí)現(xiàn)的文檔類型名叫文件夾(Folder),該文檔類型還包括了普通(common)數(shù)據(jù)架構(gòu)、都柏林(dublincore)數(shù)據(jù)架構(gòu),文件夾化(Folderish)面元;[0031]當(dāng)擴(kuò)展點(diǎn)(point)為文檔類型(doctype)1-1且其標(biāo)簽為面元(facet)1-4時(shí),會(huì)用面元描述符(FacetDescriptor)1-5實(shí)例化該名叫文件夾化(Folderish)的面元;[0032]當(dāng)擴(kuò)展點(diǎn)(point)為架構(gòu)(schema)1-6時(shí)會(huì)根據(jù)其標(biāo)簽名架構(gòu)(schema)用架構(gòu)描述符(SchemaBindDescriptor)1-8實(shí)例化該數(shù)據(jù)架構(gòu),該架構(gòu)的名為dublincore,前綴(prefix)為dc,其引用地址(src)為shcema文件夾下的dublicore.xsd文件1-9,在該例中列出了部分都柏林(dublincore)數(shù)據(jù)架構(gòu)屬性,包括字符串格式的標(biāo)題(title)、描述(descript1n)及字符串列表格式的主題(subjects)。[0033]如圖2所示,系統(tǒng)啟動(dòng)時(shí)會(huì)根據(jù)圖2左側(cè)的xml標(biāo)簽語(yǔ)言生成一張連接到postgresql數(shù)據(jù)庫(kù)的目錄:[0034]系統(tǒng)先用SQL目錄描述符(SQLDirectoryDescriptor)將IlOnsubjects目錄2-1實(shí)例化為配置信息(config)2_2,再將緩存最大容量(cacheMaxSize)2_3和緩存超時(shí)時(shí)長(zhǎng)(cacheTimeout)2-4存入緩存。根據(jù)數(shù)據(jù)源標(biāo)簽(〈dataSource〉)2-5找到其對(duì)應(yīng)的服務(wù)器配置并用獲取連接方法(getConnect1n)2-6獲取一個(gè)到Postgresql的連接,可以看到生成的連接包括了數(shù)據(jù)庫(kù)位置jdbc:postgresql://localhost:5432/postg,用戶名postgr。在架構(gòu)管理(schemaManager)中提取架構(gòu)名(schemaName)2-7為llOnxvocabulary的架構(gòu),架構(gòu)(schema)2-8展示了llOnxvocabulary對(duì)應(yīng)的屬性,包括string類型的id、parent,該架構(gòu)被實(shí)例化后的樣子如2_9所示。提取該架構(gòu)的各個(gè)字段名(fieldName)2_10并將其塞入架構(gòu)字段表(SchemaFieldMap)2-11,當(dāng)字段名2_12(同2_10)與XML中idField標(biāo)簽2-13中的內(nèi)容“id”2-14相同時(shí),設(shè)定該字段為架構(gòu)的關(guān)鍵字段并規(guī)定其不許為空如2-15所示。該字段的數(shù)據(jù)類型2-16會(huì)被設(shè)置為該欄的類型(ColumnType)2-17,如果XML中的Id自動(dòng)增加標(biāo)簽(autoincrementldField)2-18中的值為true,會(huì)通過(guò)條件判斷2-19并將該欄的類型設(shè)置為AUT0INC。如果該欄在架構(gòu)中包含默認(rèn)值2_20,會(huì)將該默認(rèn)值(defaultValue)2-21設(shè)置到該欄。最后將通過(guò)連接(sqlConnect1n)2-22(同2-6),剛組建的表(table)2-23,數(shù)據(jù)文件名(dataFiIeName)2-24,建表策略(createTablePolicy)2-25來(lái)在postgresql數(shù)據(jù)庫(kù)中建立名為IlOnsubjects的表。[0035]如圖3所示,系統(tǒng)會(huì)根據(jù)xml中的建表策略、架構(gòu)及數(shù)據(jù)源在postgresql數(shù)據(jù)庫(kù)中建立該目錄并導(dǎo)入數(shù)據(jù):[0036]當(dāng)建表策略為從不(never)3-1時(shí)直接跳過(guò)設(shè)置,當(dāng)建表策略為缺失欄目時(shí)建表(on_missing_column)3-2時(shí),會(huì)用hasMatchingColumns方法3-3檢驗(yàn)是否含有缺失行,該方法會(huì)調(diào)用getMissingColumns方法3_4來(lái)尋找缺失行,該方法會(huì)先查找數(shù)據(jù)庫(kù)中已存在的同名表(IlOnsubjects)并獲取其各欄目名如3_5所示,再獲取新載入的IlOnsubjects表3-6,將原始欄目3-5中不存在的新欄目3-7載入缺失欄目(missingColumns)3-8。如果缺失欄的尺寸大于O意味著存在缺失欄,將用addMissingColumns方法3_9為IlOnsubjects表添加新欄目label_new,再用createTable方法3_10重新建表,該方法將創(chuàng)建一個(gè)授權(quán)聲明(stmt)3-11,該聲明包括了到postgresql數(shù)據(jù)庫(kù)的連接信息2-6,用該聲明先執(zhí)行刪除舊表語(yǔ)句(dropSql)3-12,再根據(jù)新架構(gòu)執(zhí)行建表語(yǔ)句(createSql)3-13,最后再執(zhí)行設(shè)置id欄為主鍵這樣的后置建表語(yǔ)句(sql)3-14。建完表后用1adData方法3_15為該表載入數(shù)據(jù),XML通過(guò)數(shù)據(jù)文件標(biāo)簽(〈dataFile〉)3-16聲名了directories/llOnsubjects.csv為該表載入信息的地址,系統(tǒng)將把該地址(dataFiIeName)3-17中的內(nèi)容導(dǎo)入輸入信息流(InputStream)及csv解讀器(csvReader)中,通過(guò)csv解讀器提取IlOnsubjects.csv中的各欄目名(columnNames)3-18,并據(jù)此生成一條SQL插入語(yǔ)句(insertSql)3_19,將IlOnsubjects.csv中每行的內(nèi)容3-20讀取到欄目值(columnValues)3-21,并根據(jù)判斷條件把該值轉(zhuǎn)化成架構(gòu)中對(duì)應(yīng)的數(shù)據(jù)類型3-22,將這些值插入3-19組成帶參數(shù)的SQL插入語(yǔ)句3-23,執(zhí)行該語(yǔ)句后將在postgresql數(shù)據(jù)庫(kù)中插入該行的內(nèi)容如3_24所示。[0037]如圖4所示,系統(tǒng)會(huì)將XML中的下拉復(fù)選插件類型(suggestManyDirectory)注冊(cè)到系統(tǒng)中作為實(shí)例化下拉復(fù)選插件的模板,載入一個(gè)插件類型分為4步:[0038]將插件類型名(suggestManyDirectory)4-1載入4-2;將處理插件的方法(handler-class)4-3載入;將顯示插件的模板屬性(property)4-5載入4-6;將插件類型的配置信息(configurat1n)4-7通過(guò)方法4-8載入。4-8將分別將標(biāo)題(title)4-9載入4-10,將支持的模式(supportedModes)4-11載入4-12,將插件的字段組織形式(list)4-13載入4-14,將字段支持的類型(supportedTypes)4-15載入4_16,將插件包含的顯示位置列表(categories)4-17載入4_18,其中的document意味著在文檔管理界面使用該插件,將插件默認(rèn)的瀏覽布局4-19(包含“寬度suggesti0n_width”等部件)載入4-20,將插件默認(rèn)的編輯布局4-21(包含瀏覽布局的部件及編輯用的“必選required”等部件)載入4_22,可以看到編輯布局4-22的部件數(shù)[19]遠(yuǎn)多于瀏覽布局4-20的部件數(shù)[7],將編輯狀態(tài)下的默認(rèn)值(defaultValues)4-23載入4-24。最后用注冊(cè)插件類型(registerWidgetType)方法將定義好的插件類型描述符(desc)4-25注冊(cè)到默認(rèn)的jsf類別(category)4-26中:從插件類型描述符4-29中提取配置信息(configurat1n)以外的三項(xiàng)組成一個(gè)輕量級(jí)的插件類型4-27并將其載入類別為jsf的類型注冊(cè)表(typeReg)4_28中;再將插件類型描述符(desc)4-29載入類別為jsf的插件類型定義信息注冊(cè)表(defReg)4_30中。[0039]如圖5所示,系統(tǒng)會(huì)根據(jù)下拉復(fù)選插件類型(suggestManyDirectory)實(shí)例化一個(gè)能選擇主題(subjects)的下拉復(fù)選插件:[0040]5-1為該主題(subjects)下拉復(fù)選插件具體的xml配置信息,當(dāng)客戶加載的頁(yè)面包含該插件時(shí)系統(tǒng)會(huì)根據(jù)該插件的注冊(cè)信息(插件的注冊(cè)步驟同圖4中的插件類型注冊(cè)步驟)和運(yùn)行環(huán)境臨時(shí)計(jì)算生成一個(gè)插件。系統(tǒng)先通過(guò)當(dāng)前布局的模式(IayoutMode)5-2取得該插件的模式(wMode)5_3,如果插件模式等于隱藏(HIDDEN)5_4的話返回null,S卩不生成該插件。系統(tǒng)用getRequired方法5-5判斷該插件是否為必選插件,它將先用getProperties方法5_6取得該插件的當(dāng)前狀態(tài)下的屬性,該插件的所有屬性(properties)5-7為一個(gè)以any作為鍵值的哈希表,它取自于xml中的屬性標(biāo)簽(properties)5-8,系統(tǒng)先提取該插件在任何狀態(tài)下(any)的屬性5_9,該屬性為5_7中any鍵值對(duì)應(yīng)的內(nèi)容,在提取當(dāng)前插件模式(mode)5_10下的屬性5_11,該屬性為空,最后再將5-9和5-11載入5-12組成插件當(dāng)前狀態(tài)下的屬性并返回getRequired方法5-5,如當(dāng)前狀態(tài)下的屬性包含必選(required)屬性5_13則返回必選鍵值對(duì)應(yīng)的內(nèi)容(required=true就返回true)來(lái)判斷當(dāng)前插件是否為必選插件。系統(tǒng)取得該插件的類型(wType)5_14,通過(guò)getStoreCategory方法5-15來(lái)調(diào)用該插件的類別,沒(méi)設(shè)置類別的話會(huì)用getDefaultStoreCategory方法5-16返回默認(rèn)的jsf類別5-19,將該值作為參數(shù)5-17來(lái)執(zhí)行獲取插件類型定義信息getWidgetTypeDefinit1n方法5_18,該方法會(huì)根據(jù)插件類別5-19來(lái)獲取jsf類別的插件類型定義信息注冊(cè)表5-20,即圖4中注冊(cè)了插件類型的注冊(cè)表(defReg)4_30,再根據(jù)該插件的類型名5-21(同5-14中的suggestManyDirectory,插件類型名4-1)獲取該插件的類型定義信息5-22即圖4中注冊(cè)的下拉復(fù)選插件類型4-29。通過(guò)getDefaultPropertyValues方法5_23來(lái)獲取默認(rèn)屬性,5-24為插件類型的默認(rèn)屬性,它是由xml中的默認(rèn)值標(biāo)簽(defaultValues)4-23定義的,提取其任意模式下的屬性5_25及插件當(dāng)前模式5-26下的屬性5-27組成插件類型默認(rèn)屬性,將插件類型默認(rèn)屬性5-28和插件屬性5-29分別載入生成插件的總屬性(props)5-30。5-31為插件類型的默認(rèn)編輯布局(同4-21),它為最少字符(minChars)屬性5_32賦予默認(rèn)值,subjects插件繼承了該屬性5-33,插件類型提供了選擇目錄名(directoryName)5-34屬性,subjects插件為該屬性賦予IlOnsubjects值5-35規(guī)定該下拉復(fù)選插件選擇IlOnsubjects目錄下的詞匯,插件類型為寬度(width)屬性5-36賦予默認(rèn)值400,subjects插件用300覆蓋了該屬性5_38。就這樣,subjects插件以圖4中的下拉列表插件類型為模板,引用其默認(rèn)架構(gòu)并添加了新的擴(kuò)展生成了選擇主題的下拉列表插件。[0041]如圖6所示,系統(tǒng)將插件的字段及屬性變量暴露給了前臺(tái):[0042]取出插件的類型名6-1和插件的類型類別6-2,用getWidgetTypeHandler方法6-3來(lái)取得插件的處理器,該方法會(huì)用getWidgetType方法6_4取出插件類型,即通過(guò)插件類別6-5獲取類別為jsf的插件類型注冊(cè)表,該注冊(cè)表為圖4中只包含處理方法和屬性模板的輕量級(jí)插件類型注冊(cè)表4-28,再通過(guò)類型名6-7取出插件類型6-8,即圖4中的輕量級(jí)插件類型4-27,通過(guò)getWidgetTypeClass方法6_9取出該插件類型6_8的方法類6-10(同4-3),用該方法類實(shí)例化一個(gè)處理器6-12,再把插件類型6-8中的屬性模板6-11(同4-5)插入處理器,用該處理器中的getFaceletHandler方法來(lái)暴露插件變量。用getTemplateValue方法6_13獲取模板,若插件類型的模板不為空則獲取6_14,否則獲取插件的模板6-15。生成一個(gè)包含環(huán)境變量ctx和標(biāo)簽信息tagConfig的表現(xiàn)層處理器6-16,用它的getTagAttributes方法6-17創(chuàng)建標(biāo)簽屬性,bindFirstFieIdDefinit1n布爾值6-18為true的話會(huì)把第一個(gè)字段的值綁定到標(biāo)簽的value屬性上,6-19為插件的字段列表,由插件xml信息的fields標(biāo)簽6-20定義,取列表的第一個(gè)值(field)6_21,再用createExpress1nString方法6-22把該值改成express1n語(yǔ)句,該方法會(huì)對(duì)不同的字段格式進(jìn)行不同的處理,這里它用:把字段分割成數(shù)組6-23再將其組成6-24中的格式,最后用#{}將6-24括起來(lái)變成6-25中的樣式,用字段值6-25和鍵值value字符串6_26作為createAttributes方法6_27的參數(shù)來(lái)創(chuàng)建標(biāo)簽屬性,該方法將引入當(dāng)前標(biāo)簽的具體位置6-28,即layout_default_template模板中在73行77列結(jié)束的〈nxl:widget>標(biāo)簽范圍以內(nèi),所生成的標(biāo)簽屬性如6-29所示。用getAttributes方法6_30取得屬性的標(biāo)簽屬性,它將插件的每條屬性6-31,即xml信息中屬性property標(biāo)簽6_32中的內(nèi)容,取其鍵值(key)6-33,用樣式#{%s.properties.%s}把屬性轉(zhuǎn)化成6-35中的三級(jí)節(jié)點(diǎn),它是一個(gè)引用因此不會(huì)保存在緩存中,不會(huì)被ajax刷新,將鍵值6-34和引用6_35輸入方法6-27會(huì)創(chuàng)建標(biāo)簽屬性6-36。根據(jù)(id)6-37為標(biāo)簽生成一個(gè)id屬性,再用6_14中的模板生成一個(gè)template屬性(這兩個(gè)屬性都是用方法6_27生成的)。接下來(lái)計(jì)算要清染的變量,讓模板中field_0、field,I格式的字段值可用,取出標(biāo)簽中鍵值為value的屬性6-38,即我們第一個(gè)創(chuàng)建的標(biāo)簽屬性6-29(其1calName和qName都為value)中的取值(value=#{value[’dc’][’subjects’]}中等號(hào)右邊的內(nèi)容),再取出需要暴露的變量名(field)6-39(還要暴露filed_0,fieIdOrValue等),最后用createValueExpress1n方法6-43為其包裹EL標(biāo)簽,添加功能映射,6-40為封裝的表達(dá)式,6_41為封裝的變量映射,6-42為預(yù)期的Object對(duì)象。再提取插件的每條屬性6-44,據(jù)其鍵值6_45進(jìn)行格式轉(zhuǎn)化產(chǎn)生該屬性需要暴露的變量名(widgetProperty_minChars)6-46,從minChars標(biāo)簽屬性6-36中取值(value=#{widget,properties.minChars}中等號(hào)右邊的內(nèi)容),最后用方法6-43依次封裝每條屬性。[0043]如圖7所不,系統(tǒng)通過(guò)suggest_many_directory_widget_template.xhtml文件在前臺(tái)顯示插件,該文件在插件類型的屬性標(biāo)簽4-5中定義,插件暴露變量時(shí)用6-14作為值生成了一個(gè)template標(biāo)簽屬性,該屬性為顯示復(fù)選下拉插件的模板信息:[0044]xhtml先對(duì)插件狀態(tài)進(jìn)行判斷,此處當(dāng)插件為瀏覽或編輯狀態(tài)時(shí)對(duì)插件進(jìn)行顯示,先在幫助標(biāo)簽7-1中賦予label,suggest1n,help.minChars對(duì)應(yīng)的中文信息。再顯示標(biāo)簽框(valueHoIder)7-2,標(biāo)簽框中的值(value)7-3為圖6中暴露的field_0變量,它對(duì)應(yīng)的表達(dá)式6-40為#{value[’dc,][’當(dāng)前第1頁(yè)1 2 3 4 5 6