專利名稱::通過使用圖形用戶界面控件來組合Web服務(wù)的程序創(chuàng)建的制作方法
技術(shù)領(lǐng)域:
:本發(fā)明涉及在萬維網(wǎng)上編程。本發(fā)明尤其涉及使用GUI控件來組合網(wǎng)絡(luò)程序?qū)ο?Web服務(wù))以創(chuàng)建新地程序?qū)ο蟆?br>背景技術(shù):
:萬維網(wǎng)(Web)是目前流行的計(jì)算機(jī)連網(wǎng)平臺(tái),每天有數(shù)百萬的人將萬維網(wǎng)用于多種應(yīng)用,從個(gè)人電子郵件和研究目的的“網(wǎng)上沖浪”到很復(fù)雜的商業(yè)和科學(xué)使用。發(fā)展出Web是為了使因特網(wǎng)的使用簡單和容易。其概念是在用戶(客戶端)個(gè)人計(jì)算機(jī)(PC)處提供瀏覽器程序,以解釋來自使用HTML和圖形文件的主機(jī)服務(wù)器的信息。因特網(wǎng)提供通信手段以使Web客戶機(jī)和服務(wù)器互連。Web服務(wù)是可被服務(wù)器訪問并且為客戶群體實(shí)現(xiàn)功能的程序。在一個(gè)示例中,Web服務(wù)提供證券報(bào)價(jià)機(jī)信息。已知一Web服務(wù)可用的客戶可訪問該Web服務(wù)以實(shí)現(xiàn)一個(gè)操作,否則客戶必須為此創(chuàng)建一個(gè)程序。由于Web服務(wù)可用,因此客戶僅需知道如何與Web服務(wù)接口,并且客戶可將Web服務(wù)的功能并入自己的本地應(yīng)用。為了知道如何與Web服務(wù)接口,程序員需要理解接口語言。一種這樣的語言是Web服務(wù)描述語言(WSDL)(根據(jù)存在于Web上www.w3.org/TR/wsdl處的W3C標(biāo)準(zhǔn)),其是一種基于XML的語言,用于描述與Web服務(wù)的接口。作為服務(wù)器的內(nèi)容提供者運(yùn)行的Web服務(wù)向客戶程序提供WSDL文檔。該WSDL文檔定義了接口模式,從而客戶可知道Web服務(wù)接口所需的格式、協(xié)議等??蛻粜枰斫釽eb服務(wù)的功能(例如其提供證券報(bào)價(jià),并且數(shù)據(jù)被加密)。每個(gè)Web服務(wù)還定義了自身的術(shù)語。Web服務(wù)接口語言使得程序員更容易編寫代碼以將Web服務(wù)的功能并入定制的程序,但是,需要編程知識(shí)(WSDL、XML、HTML等)來實(shí)現(xiàn)這一點(diǎn)。
發(fā)明內(nèi)容本發(fā)明的目標(biāo)是簡化使用Web服務(wù)的程序創(chuàng)建。本發(fā)明提供了用戶可用的Web服務(wù)(或可選地其他程序)的列表(菜單)。程序員使用一創(chuàng)建器程序,該程序?yàn)楸景l(fā)明將支持的每個(gè)Web服務(wù)創(chuàng)建圖標(biāo)支持。一菜單放置器功能將創(chuàng)建的圖標(biāo)放置在菜單內(nèi)。還為非Web服務(wù)的定制程序創(chuàng)建圖標(biāo)。這種圖標(biāo)可用于提供例如音頻、視頻、機(jī)械接口。通過授權(quán)代理或從內(nèi)容提供者獲取圖標(biāo),使圖標(biāo)對(duì)于用戶可用。優(yōu)選地,每個(gè)圖標(biāo)均由標(biāo)題以及支持性描述文本來表示。該標(biāo)題以及可選的描述文本在用戶的客戶計(jì)算機(jī)與相關(guān)聯(lián)的通用圖標(biāo)圖像一起顯示。該圖標(biāo)包括對(duì)程序代碼的訪問、Web服務(wù)接口控件、以及可視特性。用戶選擇圖標(biāo)標(biāo)題并(使用UBI移動(dòng)器)將其拖入框架(畫布)。然后,用戶可在該框架內(nèi)執(zhí)行該圖標(biāo)以檢測其功能。用戶可將該圖標(biāo)與該框架內(nèi)的其他對(duì)象互連(使用互連器GUI1506),以創(chuàng)建新的功能。當(dāng)將圖標(biāo)拖到框架內(nèi)時(shí),優(yōu)選地創(chuàng)建更詳細(xì)的圖標(biāo),該圖標(biāo)可見地顯示了接口選擇(如果適用的話),從而當(dāng)用戶互連該對(duì)象時(shí),用戶可通過選擇(使用GUI選擇器)合適的可視表示來選擇(例如)英語或西班牙語語言轉(zhuǎn)換。用戶可使用參數(shù)設(shè)置器GUI來設(shè)定合適的參數(shù)以定制所選擇的圖標(biāo)的功能。在一個(gè)實(shí)施例中,用戶使用顯示啟動(dòng)器GUI來顯示圖標(biāo)的參數(shù)選項(xiàng);然后,使用在參數(shù)顯示上操作的操作器,用戶設(shè)定合適的參數(shù);最后,用戶使用退出器GUI來退出參數(shù)顯示。在一個(gè)實(shí)施例中,用戶可檢測定制的圖標(biāo)的功能。用戶使用啟動(dòng)器GUI來啟動(dòng)該檢測。執(zhí)行該檢測,并導(dǎo)致GUI修改器修改顯示的視覺表示以便根據(jù)檢測功能來指示該圖標(biāo)的功能狀態(tài)。該顯示可改變顏色、亮度、文本消息顯示,可進(jìn)行形狀改變或?qū)崿F(xiàn)聲音表示。在一個(gè)實(shí)施例中,由表示保存器將互連的圖標(biāo)保存為封裝體(capsule)表示。被保存的封裝體表示進(jìn)一步由封裝體圖標(biāo)表示,從而可將其添加到用戶的可用圖標(biāo)列表內(nèi)。當(dāng)用戶滿意框架內(nèi)的互連圖標(biāo)的功能時(shí),用戶將該框架結(jié)構(gòu)保存為命名的程序?qū)嶓w。將來,用戶可將該命名的程序?qū)嶓w作為單個(gè)對(duì)象來執(zhí)行。在一個(gè)實(shí)施例中,可給該命名的程序?qū)嶓w本身分配一個(gè)圖標(biāo),從而在新框架的拖放創(chuàng)建中可使用該命名的程序?qū)嶓w。因此,本發(fā)明的一個(gè)目的是為Web服務(wù)提供具有可選的可視屬性的拖放圖標(biāo)。本發(fā)明的另一個(gè)目的是提供一種用于互連拖放圖標(biāo)以創(chuàng)建新功能的機(jī)制。從下面結(jié)合附圖對(duì)本發(fā)明的詳細(xì)說明,本領(lǐng)域內(nèi)的技術(shù)人員可清楚地了解本發(fā)明的這些以及其他目的,在該些附圖中圖1是用于執(zhí)行程序應(yīng)用的計(jì)算機(jī)系統(tǒng)的高層描述。圖2是使用大量互連的計(jì)算機(jī)系統(tǒng)的計(jì)算機(jī)網(wǎng)絡(luò)的高層描述。圖3是使用本發(fā)明的GUI顯示的示例性視圖4放大了圖3的一部分以描述一圖標(biāo)列表;圖5放大了圖3的一部分以描述從圖4的列表中拖出的互連圖標(biāo);圖6示出啟動(dòng)和保存圖標(biāo)的流程;圖7示出創(chuàng)建互連的一組圖標(biāo)的流程;圖8示出執(zhí)行互連的一組圖標(biāo)的流程;圖9示出訪問SOAP封裝體的流程;圖10示出封裝體的WSDL生成的流程;圖11示出SOAP橋的流程;圖12示出IDS請求的流程;圖13示出服務(wù)器流程的一個(gè)示例;圖14示出一直線流;圖15示出一單記錄流,其中任務(wù)在不同的計(jì)算機(jī)上并行執(zhí)行;圖16示出一多記錄流,其中任務(wù)在不同的計(jì)算機(jī)上并行執(zhí)行;圖17示出一并行流;以及圖18示出具有開關(guān)操作器的流。具體實(shí)施例方式圖1示出一可用于Web或因特網(wǎng)對(duì)等網(wǎng)絡(luò)通信以及執(zhí)行面向?qū)ο蟮某绦蚶绫景l(fā)明的那些程序的示例性計(jì)算機(jī)系統(tǒng)。該系統(tǒng)包括處理器106,該處理器用于執(zhí)行從存儲(chǔ)器105取得的程序指令。存儲(chǔ)媒體107(磁的或光的)用于保存當(dāng)前沒有被處理器106操作的程序和數(shù)據(jù)?;?jì)算機(jī)(basecomputer)可選地具有外圍設(shè)備,該些外圍設(shè)備連接在該基計(jì)算機(jī)上以提供用戶接口。通常,外圍設(shè)備包括顯示器102、鍵盤104和網(wǎng)絡(luò)連接108??蛇x地,鼠標(biāo)103、打印機(jī)/掃描儀110也連接到該示例性計(jì)算機(jī)系統(tǒng)上。存儲(chǔ)媒體107中保存的程序111被頁入(pageinto)到存儲(chǔ)器105內(nèi)以便處理器進(jìn)行處理。程序111包括操作系統(tǒng)和包括例如本發(fā)明的應(yīng)用的應(yīng)用。面向?qū)ο蟮某绦蚴窃谶\(yùn)行期間生成程序?qū)ο蟮某绦?。這些對(duì)象被保存在存儲(chǔ)器105中以便由處理器執(zhí)行。圖2示出多個(gè)通過本發(fā)明可使用的本地網(wǎng)絡(luò)和因特網(wǎng)網(wǎng)絡(luò)互連的不同設(shè)計(jì)的計(jì)算機(jī)系統(tǒng)??蛻粲?jì)算機(jī)201-205直接與用戶交互,并提供了用于請求信息的裝置。服務(wù)器206-207接收客戶請求,并作為響應(yīng)執(zhí)行操作。該操作可以是僅檢索信息(例如構(gòu)成網(wǎng)頁的HTML、GIF文件),提供到因特網(wǎng)網(wǎng)絡(luò)的路徑,或觸發(fā)在服務(wù)器上運(yùn)行的定制程序(CGI腳本)或在客戶計(jì)算機(jī)上運(yùn)行的JAVA小應(yīng)用程序。還存在對(duì)等網(wǎng)絡(luò),其中一計(jì)算機(jī)可作為客戶機(jī)和服務(wù)器運(yùn)行,從而使得計(jì)算機(jī)可直接通信。術(shù)語表UDDI(通用描述、發(fā)現(xiàn)和集成)是Web服務(wù)和Web上的企業(yè)名稱、產(chǎn)品以及位置的基于XML的注冊庫。WSFL(Web服務(wù)流語言)是由IBM設(shè)計(jì)的用于描述Web服務(wù)組合的基于XML的語言。其依賴于并補(bǔ)充其他規(guī)范例如SOAP、WSDL、XMLP和UDDI等。SOAP(簡單對(duì)象訪問協(xié)議)是用于交換信息的基于XML的協(xié)議。SOAP包括一包封(envelope),該包封定義了一個(gè)用于描述消息以及如何處理消息的框架、編碼規(guī)則以及用于代表遠(yuǎn)程過程的約定。XMLP是一組控制XML消息的格式和處理以及應(yīng)用交互的正式約定。IDS(智能決策服務(wù)器),也稱DIS(分布式綜合解決方案),見轉(zhuǎn)讓給IBM的美國專利6094655(Roger等人)“MethodofcreatingandusingNotesdecisioncapsules”。IDS執(zhí)行所選擇的身為串在一起的封裝體元件的程序封裝體。Web服務(wù)是通??衫萌f維網(wǎng)從遠(yuǎn)程服務(wù)器得到的應(yīng)用。Web服務(wù)優(yōu)選地使用WSDL(描述Web服務(wù)的接口的基于XML的文檔)對(duì)自身進(jìn)行描述。提供目錄(在概念上,其相當(dāng)于電話號(hào)碼簿),從而可用戶可發(fā)現(xiàn)可用的服務(wù),優(yōu)選地為UDDI。還提供了用于在Web服務(wù)和其客戶之間通信的工具,優(yōu)選地為SOAP。本發(fā)明是在Web服務(wù)環(huán)境以及以下文獻(xiàn)中說明的現(xiàn)有技術(shù)上發(fā)展而來的美國專利6094655“MethodofcreatingandusingNotesdecisioncapsules”(Roger等人);美國專利5710918“AmethodfordistributedtaskfulfillmentofWebbrowserrequests”;美國專利5701451“AMethodforfulfillingrequestsofawebBrowser”;美國專利5721908“ComputernetworkforWWWserverdataaccessoverInternet”;美國專利5752246“AserviceagentforfulfillingrequestsofaWebbrowser”;美國專利5745754“Asub-agentforfulfillingrequestsofaWebbrowserusinganintelligentagentandprovidingareport”;以及美國專利5974441“WWWclientserverinteractivesystemmethodwithJava”。所有這些專利都轉(zhuǎn)讓給了美國國際商業(yè)機(jī)器公司(IBM),并且被并入本文中作為參考文獻(xiàn)。隨著Web服務(wù)在因特網(wǎng)上的出現(xiàn),使用這些服務(wù)建立新應(yīng)用成為一種新的開發(fā)應(yīng)用的方法。通常,Web服務(wù)由獨(dú)立的組開發(fā),而以有意義的方式將這些服務(wù)組合在一起并不容易實(shí)現(xiàn)。本發(fā)明允許非開發(fā)人員在一個(gè)“封裝的”過程流(processflow)中創(chuàng)建、組合、包裝并一起使用這些服務(wù)。本發(fā)明提供了一種用于組合和封裝可能從未打算合作的Web服務(wù)的方法。本發(fā)明提供了一種定義Web服務(wù)之間的連接,并建立(Web)服務(wù)工作流的組合的方法。這些通過連接而組合的服務(wù)被成為封裝體(在一過程流中連接在一起的Web服務(wù)序列)。在我們的方法中,一Web服務(wù)的輸出被原樣獲得,并用作另一個(gè)Web服務(wù)(或一組并行的Web服務(wù))的輸入?;蛘撸蛇x地,一Web服務(wù)的輸出在被用作另一個(gè)Web服務(wù)的輸入之前被轉(zhuǎn)換和變換。變換器是本地服務(wù)的功能(成套工具的一部分),或者在另一實(shí)施例中,變換是由變換器Web服務(wù)實(shí)現(xiàn)的。這些Web服務(wù)的組合或封裝的過程流(封裝體)均可由不需要具有程序員的技能的用戶(使用我們提供的工具)使用“可視流構(gòu)造器”(用于Web服務(wù)的封裝體)構(gòu)建。在一個(gè)實(shí)施例中,該工具具有UDDI集成,從而用戶可訪問因特網(wǎng)上的任何Web服務(wù),并將該服務(wù)并入它們的封裝體內(nèi)。然后保存該封裝體以及其所有屬性以便以后使用。該保存的封裝體或者在工具內(nèi)被檢索并執(zhí)行,或者作為一Web服務(wù)被導(dǎo)出以便可被其他應(yīng)用使用(例如經(jīng)由UDDI)。在該工具內(nèi)執(zhí)行還可用于調(diào)試目的。該工具在執(zhí)行一個(gè)流時(shí)向用戶提供信息反饋。例如,在封裝體執(zhí)行時(shí),通過突出顯示當(dāng)前執(zhí)行的Web服務(wù)來描述從Web服務(wù)到變換器到Web服務(wù)的事件的流。在一個(gè)實(shí)施例中,當(dāng)Web服務(wù)執(zhí)行時(shí),代表該Web服務(wù)的可視圖標(biāo)是綠色的,當(dāng)Web服務(wù)空閑時(shí)圖標(biāo)是白色的,而在Web服務(wù)檢測到錯(cuò)誤時(shí)圖標(biāo)是紅色的。本發(fā)明提供了一種非編程裝置,用于將Web服務(wù)組合(封裝)起來,以開發(fā)可以是部分或全部應(yīng)用、或者“超級(jí)”服務(wù)(然后可作為一個(gè)Web服務(wù)被提供的Web服務(wù)組合)的過程工作流。本發(fā)明提供了一種用于定義這些服務(wù)組合(封裝體)的方法,從而可創(chuàng)建、查看和修改這些組合。(可視流構(gòu)造器)。本發(fā)明提供了一種用于保存和檢索這些封裝體以便進(jìn)行修改、分發(fā)(例如,分發(fā)給UDDI注冊庫或Web應(yīng)用或產(chǎn)品)和/或執(zhí)行(帶有調(diào)試能力)的方法。本發(fā)明提供了一種用于在因特網(wǎng)(或互聯(lián)網(wǎng))或環(huán)境組合上執(zhí)行具有可視反饋的過程工作流(封裝體)的方法。系統(tǒng)以下面的方式創(chuàng)建Web服務(wù)圖標(biāo)。根據(jù)對(duì)Web服務(wù)的WSDL的分析,系統(tǒng)了解Web服務(wù)的(一個(gè)或多個(gè))方法的簽名和返回類型。然后,系統(tǒng)創(chuàng)建該方法的文字/圖標(biāo)表示。在一個(gè)實(shí)施例中,每個(gè)方法都是一多行的框。第一行是Web服務(wù)的名稱,第二行是方法的名稱和返回類型,第三行和余下的行(如果存在的話)代表輸入?yún)?shù)的類型。創(chuàng)建本地Web服務(wù)目錄Web服務(wù)封裝體構(gòu)造器提供了三種用于將可用的Web服務(wù)編目的方法。第一種方法是查詢UDDI服務(wù)器(Web服務(wù)的事實(shí)上的目錄)。第二種方法是借助于使用基于XML的文檔的文件系統(tǒng)。第三種方法是通過在可視WSDL創(chuàng)建器中輸入一服務(wù)的所有方面,來將該服務(wù)添加到本地目錄中。不管使用什么方法,構(gòu)建服務(wù)封裝體是通過首先收集建立希望的流所需的所有服務(wù)來完成的。服務(wù)封裝體構(gòu)造器301的左邊面板302是WSDL瀏覽器,其提供用于查看服務(wù)和可從這些服務(wù)得到的方法/功能的一般界面。可利用本
技術(shù)領(lǐng)域:
中已知的方法來創(chuàng)建可用Web服務(wù)的本地列表302。例如,可通過從可從一網(wǎng)站得到的中心列表中選擇來手動(dòng)地創(chuàng)建該列表。該列表可以層級(jí)分組的形式提供,以便易于導(dǎo)航。在一個(gè)實(shí)施例中,參照圖4,定制的Web服務(wù)封裝體瀏覽器工具從本地文件目錄或經(jīng)由HTTP或FTP或UDDI遠(yuǎn)程站點(diǎn)查詢可用的WSDL文檔,根據(jù)用戶輸入的標(biāo)準(zhǔn)來分析該些文檔,并創(chuàng)建代表Web服務(wù)401-406的Web服務(wù)圖標(biāo)的列表302。每個(gè)Web服務(wù)(例如BlueMail402)可具有一個(gè)或一個(gè)以上暴露的方法,該方法由顯示為該Web服務(wù)的子節(jié)點(diǎn)的方法圖標(biāo)(對(duì)于BlueMail402,為“*xsdstringsend...”)表示。例如,用戶從該定制的Web服務(wù)瀏覽器中的菜單中選擇File/ImportWSDL,瀏覽到一文檔目錄并選擇Number2Text.wsdl。然后,系統(tǒng)讀取該WSDL,對(duì)其進(jìn)行分析,并創(chuàng)建一個(gè)具有g(shù)etNumber2Text方法作為其子節(jié)點(diǎn)的Number2TextWeb服務(wù)節(jié)點(diǎn)。Number2TextWeb服務(wù)節(jié)點(diǎn)由一Web服務(wù)圖標(biāo)(鈴鐺)表示,而getNumber2Text方法由Web服務(wù)方法圖標(biāo)(球或*)302表示。構(gòu)建封裝體給定一填充了的服務(wù)列表302,則可開始封裝體的構(gòu)造。創(chuàng)建一新的Web服務(wù)封裝體303完成了兩方面的工作。首先,其提供了這樣的空間(稱為封裝體畫布),在該空間內(nèi)可安排、鏈接。查看或測試單個(gè)服務(wù),其次,該封裝體用作該服務(wù)的命名的容器。即使可使用多個(gè)Web服務(wù)來定義一個(gè)封裝體,但是封裝體本身303代表了單個(gè)服務(wù)。因此,通過創(chuàng)建封裝體303,就創(chuàng)建了一個(gè)Web服務(wù),該Web服務(wù)的功能是其包含的服務(wù)501-503的流。參照圖5,在將一Web服務(wù)圖標(biāo)拖放到新的封裝體303的流構(gòu)造區(qū)內(nèi)之后,優(yōu)選地創(chuàng)建一更詳細(xì)的圖標(biāo),該圖標(biāo)優(yōu)選地包括兩行或更多行。每行均提供一用于選擇用于該Web服務(wù)的選項(xiàng)的GUI手段。選項(xiàng)可包括參數(shù)選擇、文本個(gè)性化,或用于使一個(gè)以上的輸入或輸出與該Web服務(wù)圖標(biāo)互連的可選擇的互連接觸點(diǎn)。例如,“翻譯器”Web服務(wù)502具有5行。第一行505是該Web服務(wù)的名稱,在此情況下是“翻譯器”。第二行506是方法的名稱和返回類型,在此情況下,該名稱為“翻譯”,而該返回類型為“xsdstring”。第三行507到第五行509是方法簽名,在此情況下為“xsdstringmtlang”507、“xsdstringtext”508、“xsdstringoption”509?!皒sdstring”是輸入?yún)?shù)的類型。Mtlang507是將要翻譯成的語言。Text508是將翻譯的文本。選項(xiàng)509是輸出的格式,文本或HTML。例如,為了調(diào)用此Web服務(wù)以便將文本從英語翻譯成西班牙語,用戶需要右鍵點(diǎn)擊第三行507,其生成一彈出窗口(未示出)。然后用戶在該彈出窗口中將mtlang設(shè)定為Spanish。接下來,用戶右鍵點(diǎn)擊第四行508,并將文本設(shè)定為希望的詞/句。最后,用戶右鍵點(diǎn)擊第五行509,將選項(xiàng)設(shè)定為“text”、“HTML”或讓其空白。應(yīng)理解,XSD是一XML前綴,其指示XML模式名稱空間“www.w3.org/2001/XMLSchema”,并符合XML模式約定?!皒sditem”,例如xsdstring,用于標(biāo)識(shí)輸入?yún)?shù)的類型或返回方法的類型。在用戶將Web服務(wù)拖放到流面板(畫布)內(nèi)、連接這些Web服務(wù)并設(shè)定所需的輸入?yún)?shù)之后,就創(chuàng)建了一封裝體。在后臺(tái),還創(chuàng)建一代表Web服務(wù)對(duì)象以及Web服務(wù)之間的交互的圖形數(shù)據(jù)結(jié)構(gòu)。當(dāng)用戶從File菜單選擇Save或Saveas時(shí),使用Java對(duì)象串行化將該圖形數(shù)據(jù)結(jié)構(gòu)作為WSFL保存到硬盤中。在一個(gè)實(shí)施例中,保存的封裝體可被添加到用戶的Web服務(wù)菜單302中。將Web服務(wù)401-406從服務(wù)列表302拖放入封裝體畫布303會(huì)可視地實(shí)例化資源,并且在一優(yōu)選實(shí)施例中為Web服務(wù)創(chuàng)建詳細(xì)的圖標(biāo)。其由該服務(wù)的名稱、從該服務(wù)504-517使用的功能、以及該服務(wù)運(yùn)行所需的輸入和輸出表示。在此示例中,將“Number2Text”服務(wù)501拖入封裝體畫布303。此服務(wù)取得一個(gè)數(shù)字并用英語拼出該數(shù)字(例如,輸入“1”變?yōu)檩敵觥皁ne”)。使用一個(gè)數(shù)字—在此情況下為號(hào)碼1-來初始化Number2Text501。如果該封裝體作為一個(gè)Web服務(wù)被調(diào)用(見調(diào)用/使用封裝體),則也可指定此數(shù)字。然后,將翻譯服務(wù)“翻譯器”502拖入封裝體畫布303。將Number2Text501的輸出連接到該翻譯器的輸入。手動(dòng)地將該翻譯器設(shè)置成將英語翻譯成西班牙語。如果運(yùn)行此封裝體或服務(wù)流,則它會(huì)調(diào)用該Number2Text服務(wù)501并返回“one”。它會(huì)將該結(jié)果傳給翻譯器服務(wù)502并將“one”翻譯成“uno”。在該流執(zhí)行時(shí),突出顯示當(dāng)前的服務(wù),并且連接箭頭用紅色和綠色可視地指示成功和失敗??梢钥梢暤貦z查和分析從一個(gè)服務(wù)到另一個(gè)服務(wù)的流。隨著封裝體復(fù)雜性的增加,這被證明是非常有教益的??衫枚喾N本
技術(shù)領(lǐng)域:
內(nèi)的技術(shù)人員熟悉的方法來實(shí)現(xiàn)執(zhí)行可視化??商砑觿?dòng)畫來顯示在測試中的功能??衫寐曇魜頂U(kuò)充該可視表示,以進(jìn)一步提高功能的可視化。例如在當(dāng)前的示例中,動(dòng)畫人物例如行走的人形可將消息從圖標(biāo)傳送到圖標(biāo),同時(shí)被突出顯示的圖標(biāo)或互連表現(xiàn)了正被可視化的項(xiàng)目。然后,計(jì)算機(jī)用話音消息如同動(dòng)畫人物在評(píng)論那樣指示,例如當(dāng)可行時(shí)指示“看起來很好”,當(dāng)懷疑存在問題時(shí)指示“唔-哦”,或甚至指示描述可能的改正“你還沒有告訴我在’翻譯器’步驟中使用哪種語言”的話音消息。通過將“BlueMail”服務(wù)503(因特網(wǎng)郵件服務(wù))拖入畫布303,提供了一個(gè)將該流的結(jié)果用電子郵件發(fā)送給收信人的機(jī)制。在此情況下,將收件人(to)字段512設(shè)定為webahead@us.ibm.com。將發(fā)件人(from)字段515設(shè)定為Web服務(wù)封裝體email-test.wsfl。將主題(subject)字段516設(shè)定為Number2TextTranslationTest。最后,將翻譯器502的輸出連接到電子郵件服務(wù)503的消息輸入。在此時(shí),運(yùn)行該封裝體可實(shí)現(xiàn)與上述相同的功能,不過另外還將結(jié)果用電子郵件發(fā)送給webahead@us.ibm.com。最后被拖到封裝體的畫布303中的項(xiàng)是可視報(bào)警修改器518。在一個(gè)實(shí)施例中,該可視的報(bào)警圖標(biāo)可從用戶的工具欄411得到。在其他實(shí)施例中,用戶的瀏覽器包括這樣的本地程序的列表,該些本地程序可以與來自Web服務(wù)列表302中的Web服務(wù)相同的方式被拖入畫布,并且添加到流中。修改器是交互地改變流的項(xiàng)目。在此示例中,報(bào)警修改器518僅利用郵件服務(wù)的結(jié)果輸出生成一“報(bào)警”對(duì)話框。該修改器518將通過報(bào)警對(duì)話框?qū)⒁蛱鼐W(wǎng)郵件操作的成功或失敗告知用戶。其他的修改器可取得一字符串并將其轉(zhuǎn)化為整數(shù)(例如“001”變?yōu)?)。調(diào)用/使用封裝體對(duì)于完成的Web服務(wù)封裝體303,可用三種方式中的任何一種調(diào)用它。第一種方式是手動(dòng)運(yùn)行。這涉及按下“play”按鈕或類似物。第二種方式是以定期的方式調(diào)用封裝體。例如,可每隔一個(gè)小時(shí)調(diào)用服務(wù)。第三種方式是通過SOAP服務(wù)器插件調(diào)用封裝體。該SOAP服務(wù)器插件提供了兩個(gè)功能。一個(gè)功能是能夠作為UDDI服務(wù)器被查詢。當(dāng)客戶請求所有開啟的服務(wù)/封裝體時(shí),插件將返回遵循UDDI和WSDL標(biāo)準(zhǔn)的動(dòng)態(tài)生成的響應(yīng)。當(dāng)查詢服務(wù)器時(shí),該服務(wù)器將發(fā)送封裝體名稱作為服務(wù)名稱,作為由將被調(diào)用的第一服務(wù)確定的輸入列表的輸入,以及由最后一個(gè)服務(wù)的輸出限定的輸出。另一個(gè)功能是SOAP插件擔(dān)當(dāng)一接口來運(yùn)行封裝體,就好像封裝體是Web服務(wù)似的。當(dāng)外部客戶請求SOAP服務(wù)器插件。后者轉(zhuǎn)而調(diào)用指定的封裝體時(shí),會(huì)發(fā)生調(diào)用。通過這種方式,封裝體可用作新封裝體的組件。本發(fā)明的一個(gè)部分是IDSSOAP橋,其為IDS提供了類似的功能。IDS是基于封裝體的報(bào)告環(huán)境。該IDSSOAP橋提供了對(duì)IDS的SOAP訪問。由于該橋?qū)⑵浔旧砉鏋閃eb服務(wù),因此IDS封裝體可被集成到封裝體流中。參照圖3,在優(yōu)選實(shí)施例中,Web服務(wù)封裝體構(gòu)造器GUI301包括兩個(gè)框架302、303。一個(gè)框架顯示可用于構(gòu)建新的封裝體的可用服務(wù)的服務(wù)列表302。另一個(gè)框架顯示封裝體303,在封裝體完成時(shí)其將包括來自第一個(gè)框架的互連的服務(wù)。參照圖4,其示出服務(wù)列表302的一優(yōu)選實(shí)施例的示例。該服務(wù)列表包括可用于封裝的服務(wù)401-406。在一個(gè)實(shí)施例中,該些服務(wù)包括遠(yuǎn)程服務(wù)和本地Web服務(wù)的混合。可拖入容器的、該列表中的每個(gè)服務(wù)均由一圖標(biāo)指示。一些服務(wù)401、402、405還包括關(guān)于該服務(wù)的附加信息。參照圖5,其示出已由本發(fā)明創(chuàng)建的示例性封裝體303。已將三個(gè)Web服務(wù)501-503放入該封裝體303,并且用戶已將這三個(gè)服務(wù)互連。本地服務(wù)518已被放入并連接到第三個(gè)Web服務(wù)503的輸出。參照圖6,其示出服務(wù)流初始化。向UDDI服務(wù)器查詢可用的服務(wù)(步驟601)。使用查詢的結(jié)果,用候選的Web服務(wù)圖標(biāo)更新本地服務(wù)目錄(步驟602)。用戶可使用該本地服務(wù)目錄來向服務(wù)列表302選擇性地添加服務(wù)。一旦在封裝體303中創(chuàng)建一新的服務(wù)流(步驟603),則將其保存在本地文件中以便將來使用(步驟604)。在優(yōu)選實(shí)施例中,用基于XML的WSFL語言描述該新的流。將該命名的封裝體可選地添加到服務(wù)列表302中,來作為一個(gè)可拖入新的封裝體303的新服務(wù)流。圖7中示出創(chuàng)建一服務(wù)流封裝體的示例。在步驟701,在GUI顯示301中打開新的封裝體303。在步驟702,將第一服務(wù)拖放入該封裝體303。在步驟703,將第二服務(wù)拖放入該封裝體303。在步驟704,將該第一服務(wù)的輸出連接到該第二服務(wù)的輸入。在步驟705,選擇用于該第二服務(wù)的選項(xiàng)。在步驟706,將第三服務(wù)拖放入該封裝體303。在步驟707,將該第三服務(wù)的輸入連接到該第二服務(wù)的輸出。在步驟708,將第四服務(wù)拖放入該封裝體并使該服務(wù)與第三服務(wù)相連接,該第四服務(wù)是一本地服務(wù)。該封裝體完成。在步驟709,可手動(dòng)地運(yùn)行該封裝體以驗(yàn)證其功能。圖8示出服務(wù)流的執(zhí)行。在步驟801,通過GUI顯示打開并示出一服務(wù)流??赏ㄟ^按下GUI“play”按鈕420(在步驟802)或通過SOAP服務(wù)器插件(步驟803)來運(yùn)行該服務(wù)流。圖9示出示例性的Web服務(wù)流SOAP服務(wù)插件的操作。在步驟901,接收到對(duì)封裝體的請求。在步驟902,對(duì)照本地已知的服務(wù)檢查該名稱空間。如果沒有發(fā)現(xiàn)封裝體,則報(bào)告異常。如果發(fā)現(xiàn)一封裝體(步驟903)但是沒有加載該封裝體,則從該封裝體的源加載該封裝體(步驟905)。當(dāng)加載了所請求的封裝體時(shí),可執(zhí)行該封裝體(步驟906),并返回該封裝體的執(zhí)行結(jié)果(步驟907)。圖10示出Web服務(wù)流的WSDL生成。在步驟1001,接收到對(duì)命名的封裝體的“WSDL”的請求。在步驟1002,對(duì)照已知的服務(wù)檢查該名稱空間。如果沒有發(fā)現(xiàn)封裝體(步驟1003),則報(bào)告異常。如果發(fā)現(xiàn)一封裝體但是沒有加載該封裝體(步驟1004),則在步驟1005,加載該封裝體。在步驟1006,可選地檢查該封裝體的輸出和輸入,并且在步驟1007,返回動(dòng)態(tài)生成的“WSDL”。圖11示出IDSSOAP橋流。在步驟1101,接收到對(duì)“IDS”操作的請求。在步驟1102,提交對(duì)“IDS”系統(tǒng)的操作請求。在步驟1103,返回“IDS”對(duì)象或指定的數(shù)據(jù)類型,并且在步驟1104,返回用于異步操作的可選的跟蹤令牌。圖12示出經(jīng)由ISB獲取異步請求。在步驟1204,接收到對(duì)經(jīng)由跟蹤令牌的“IDS”操作的請求。在步驟1205,檢查“IDS”服務(wù)器操作。如果不允許經(jīng)由該令牌的操作(步驟1206),則報(bào)告異常。如果允許經(jīng)由該令牌的操作,則返回“IDS”對(duì)象或指定的數(shù)據(jù)類型(步驟1207)。在步驟1208,返回可選的完成百分比的信息。盡管對(duì)于理解本發(fā)明不是必須的,但是在附錄A中提供了一示例性的實(shí)現(xiàn)。版權(quán)所有者并不反對(duì)相關(guān)專利事務(wù)所內(nèi)的任何人進(jìn)行摹真復(fù)制,然而在別的方面卻保留所有版權(quán)權(quán)利。下面給出對(duì)該文檔的簡短描述Block.java==這個(gè)類提供了Web服務(wù)的構(gòu)件塊的基本實(shí)現(xiàn)。DragTree.java==這個(gè)類提供了可從其中拖動(dòng)服務(wù)對(duì)象的樹組件。FlowPane.jave==這個(gè)類實(shí)現(xiàn)了用戶可在其中拖放Web服務(wù)對(duì)象或者設(shè)置該Web服務(wù)對(duì)象的屬性的工作區(qū)。Link.java==這個(gè)類實(shí)現(xiàn)了Web服務(wù)對(duì)象之間的連接組件。Operation.java==這個(gè)類提供了Web服務(wù)方法調(diào)用的表示。ParamInputDialog.java==這個(gè)類提供了用于向Web服務(wù)方法調(diào)用設(shè)置參數(shù)的對(duì)話框。Service.java==代表一Web服務(wù)對(duì)象的核心類。WorkFlowFrame.java==這個(gè)類代表包含一個(gè)FlowPane的內(nèi)部框架。WorkSpace.java==這個(gè)類代表包含工作流的集合的工作空間。提出了根據(jù)本發(fā)明創(chuàng)建的封裝體的一些應(yīng)用。在一個(gè)實(shí)施例中,經(jīng)由網(wǎng)絡(luò)協(xié)議例如SOAP、RPC、HTTP接收到的遠(yuǎn)程請求調(diào)用根據(jù)本發(fā)明的Web封裝體。在另一個(gè)實(shí)施例中,封裝體的元件并不阻止封裝體的成功執(zhí)行和/或?qū)ν獠空埱蟮捻憫?yīng)。在另一個(gè)實(shí)施例中,通過為遠(yuǎn)程應(yīng)用提供WSDL表示來將根據(jù)本發(fā)明的封裝體集成到遠(yuǎn)程應(yīng)用。這種WSDL可被動(dòng)態(tài)生成。在另一個(gè)實(shí)施例中,圖標(biāo)與封裝體修改器相結(jié)合。封裝體修改器可表示邏輯非、與、或、異或、與非。此外,封裝體修改器可包括并行、開關(guān)和數(shù)據(jù)連接。根據(jù)本發(fā)明的封裝體Web服務(wù)由一個(gè)或多個(gè)資源(資源可以是其他Web服務(wù)、開關(guān)/并行路徑以及其他“內(nèi)置的”功能例如GUI報(bào)警或媒體播放)構(gòu)成,所述封裝體Web服務(wù)由于提供一種從外部(遠(yuǎn)程)資源調(diào)用封裝體流的方法而被增強(qiáng)。下面的示例說明了遠(yuǎn)程系統(tǒng)/用戶如何與本發(fā)明相交互來利用Web服務(wù)封裝體流。從遠(yuǎn)程計(jì)算機(jī)調(diào)用一封裝體流。該遠(yuǎn)程計(jì)算機(jī)使用網(wǎng)絡(luò)協(xié)議與主機(jī)通信。在一優(yōu)選的實(shí)現(xiàn)中,該遠(yuǎn)程計(jì)算機(jī)能夠進(jìn)行一連串“調(diào)用”,來請求可用的服務(wù)封裝體的列表,和如何調(diào)用特定封裝體的特定細(xì)節(jié),或者進(jìn)行調(diào)用封裝體的實(shí)際請求。這些“調(diào)用”事務(wù)優(yōu)選地是根據(jù)公開的當(dāng)前技術(shù)標(biāo)準(zhǔn)的HTTP上的SOAP。遠(yuǎn)程計(jì)算機(jī)向封裝體環(huán)境查詢可用Web服務(wù)流的列表。遠(yuǎn)程計(jì)算機(jī)優(yōu)選地向所有可用的封裝體發(fā)送一個(gè)一般請求。此請求可選地更具體,例如僅請求例如所有以字母“A”開頭的封裝體。主機(jī)服務(wù)器返回的響應(yīng)是與該初始請求相匹配的服務(wù)的列表。優(yōu)選地,這可使用UDDI請求和響應(yīng)來完成。在一個(gè)實(shí)施例中,遠(yuǎn)程計(jì)算機(jī)對(duì)在封裝體環(huán)境中寄居的一特定封裝體進(jìn)行查詢。遠(yuǎn)程計(jì)算機(jī)發(fā)送一個(gè)查詢,該查詢指定了用于該封裝體服務(wù)的特定標(biāo)識(shí)符。來自主機(jī)的響應(yīng)是一個(gè)文檔,該文檔足夠詳細(xì)地定義了給定服務(wù)封裝體的輸入和輸出,以隨后向主機(jī)系統(tǒng)發(fā)送調(diào)用請求。優(yōu)選地,該響應(yīng)使用WSDL標(biāo)準(zhǔn)來完整地描述封裝體期望的輸入和輸出。遠(yuǎn)程計(jì)算機(jī)調(diào)用在封裝體環(huán)境中寄居的封裝體服務(wù)流。該遠(yuǎn)程計(jì)算機(jī)指定其希望調(diào)用的特定封裝體服務(wù),和由先前的對(duì)服務(wù)描述(WSDL)的調(diào)用指定的所需的任何參數(shù)。對(duì)該調(diào)用請求的響應(yīng)由該服務(wù)描述限定。在一優(yōu)選的實(shí)現(xiàn)中,此事務(wù)使用HTTP上的SOAP和WSDL來通信和描述。例如計(jì)算機(jī)A查詢計(jì)算機(jī)B,來請求所有可用的服務(wù)(封裝體流)。計(jì)算機(jī)B以可用封裝體Web服務(wù)流的列表作為響應(yīng)。計(jì)算機(jī)A決定使用計(jì)算機(jī)B上的服務(wù)A。計(jì)算機(jī)A對(duì)計(jì)算機(jī)B進(jìn)行適當(dāng)?shù)恼{(diào)用,來調(diào)用該封裝體流(服務(wù)A)作為Web服務(wù)。計(jì)算機(jī)B執(zhí)行該封裝體流并將結(jié)果返回計(jì)算機(jī)A。在一個(gè)實(shí)施例中,本發(fā)明的Web封裝體被外部集成,并且在客戶機(jī)側(cè)或在服務(wù)器側(cè)被可視地設(shè)計(jì)、配置和管理。經(jīng)由Web服務(wù)接口遠(yuǎn)程訪問封裝體優(yōu)選地使用HTTP上的SOAP完成。在優(yōu)選實(shí)現(xiàn)中,服務(wù)器模仿HTTP協(xié)議,適當(dāng)?shù)仨憫?yīng)任何格式正確的請求。當(dāng)一消息的目標(biāo)是一封裝體服務(wù)時(shí),如果該消息不是一個(gè)格式正確的SOAP消息,則該服務(wù)器返回一錯(cuò)誤。通過相同的用于構(gòu)建封裝體的拖放界面來管理此服務(wù)器的消息流。圖13示出一ApacheWeb服務(wù)器的服務(wù)器事件流。這是服務(wù)器如何經(jīng)常具有一系列步驟需要完成以生成響應(yīng)的示例。與此類似的服務(wù)器或流都能夠利用封裝體的概念來提供高的可定制性和靈活性。對(duì)于流中的每一步驟,用戶會(huì)將圖標(biāo)拖放到桌面上來完成此系統(tǒng)。例如,可開發(fā)一個(gè)定制的認(rèn)證機(jī)制,其中將該機(jī)制拖放在打算發(fā)生認(rèn)證的點(diǎn)上。另一個(gè)進(jìn)行內(nèi)容編碼的圖標(biāo),可被拖放在該流的末端。內(nèi)容編碼獲取一組數(shù)據(jù),并以特定方式將其編碼。在此例中,它可應(yīng)用壓縮算法。此外,這些圖標(biāo)可實(shí)際表示和執(zhí)行其他流。對(duì)于圖13中所示的Apache流中的每一步驟,將代表一個(gè)模塊。這個(gè)流被認(rèn)為是線性流。參照圖13,下面的一組事件說明了一個(gè)簡單的HTTP流;接收消息1302,分析消息1304,檢查被請求的資源,響應(yīng)消息1310。當(dāng)然,可使用由Rogers等人定義的封裝體桌面來管理任何事件流。所提供的拖放模塊之一可以是認(rèn)證處理器。在一個(gè)優(yōu)選實(shí)施例中,服務(wù)器流接收請求消息,對(duì)該消息解碼,檢查以確定資源存在,然后響應(yīng)該請求。希望對(duì)某些請求限制訪問。將認(rèn)證處理器(模塊)拖放到流內(nèi)將提供此功能。該流變?yōu)榻邮照埱?302,分析消息1304,檢查認(rèn)證1306,檢查資源1308,然后響應(yīng)1310。該流也可按不同的順序進(jìn)行接收請求,分析,檢查響應(yīng),檢查授權(quán)并然后響應(yīng)。此外,如果需要的話,檢查授權(quán)和檢查資源可并行執(zhí)行。響應(yīng)模塊1310將僅以這兩個(gè)“檢查”模塊的結(jié)果作為輸入,來確定合適的響應(yīng)。如圖13所示,請求1301被處理并變?yōu)殚喿x后的請求1302。在1303轉(zhuǎn)換該請求,并在1304分析頭部。在訪問控制1305之后,在1306檢查認(rèn)證并在1307檢查授權(quán)。檢查文件Mime類型并且結(jié)果通過修正階段。響應(yīng)1310被發(fā)送給請求1301,并在1311被記入日志。在1312進(jìn)行清除,并且在1313系統(tǒng)等待一個(gè)新請求。在每個(gè)階段,如圖所示在1311將過程記入日志。在一個(gè)實(shí)施例中,Web封裝體在遠(yuǎn)程機(jī)器中運(yùn)行。其他機(jī)器是群集的或網(wǎng)格使能的。在一個(gè)實(shí)施例中,已創(chuàng)建根據(jù)本發(fā)明的Web服務(wù)封裝體,則在遠(yuǎn)程封裝體使能的服務(wù)器上執(zhí)行該封裝體。用戶將該封裝體拖放到封裝體桌面的一個(gè)區(qū)域內(nèi)以使能網(wǎng)絡(luò)連接。拖放僅是啟動(dòng)網(wǎng)絡(luò)連接的一種方式。還可簡單地創(chuàng)建一網(wǎng)絡(luò)連接并發(fā)送請求。從本地桌面到遠(yuǎn)程服務(wù)器的通信包括使用網(wǎng)絡(luò)協(xié)議到一個(gè)或多個(gè)服務(wù)器的網(wǎng)絡(luò)連接。在一優(yōu)選實(shí)現(xiàn)中,此網(wǎng)絡(luò)連接將使用HTTP上的SOAP。遠(yuǎn)程服務(wù)器被單獨(dú)表示為或組合為一個(gè)一般“服務(wù)器以太”(serverether)。用戶將選擇的封裝體流拖放到表示一個(gè)單獨(dú)的遠(yuǎn)程服務(wù)器或群集的組的圖標(biāo)上。這啟動(dòng)一個(gè)網(wǎng)絡(luò)請求以處理該Web服務(wù)封裝體。在一個(gè)優(yōu)選實(shí)現(xiàn)中,群集的組隨機(jī)地選擇一個(gè)服務(wù)器以在其上執(zhí)行該封裝體,或者可選地在每個(gè)服務(wù)器上執(zhí)行該封裝體。然后將封裝體發(fā)送給遠(yuǎn)程服務(wù)器以便執(zhí)行。在一個(gè)優(yōu)選實(shí)現(xiàn)中,該封裝體是在XML消息中描述的,該消息包括必要組件的身份,將調(diào)用哪些Web服務(wù),可在何處發(fā)現(xiàn)這些Web服務(wù),將以什么順序調(diào)用它們以及將哪些結(jié)果傳送給哪些Web服務(wù)。在一個(gè)實(shí)施例中,所述結(jié)果是在流中最后執(zhí)行的服務(wù)的結(jié)果。這類似于遠(yuǎn)程訪問封裝體的情況。在另一個(gè)實(shí)施例中,該結(jié)果可以是捕獲了該流的每個(gè)請求和響應(yīng)消息的文檔,從而可在本地機(jī)器上嚴(yán)格地重放這些事件。在一個(gè)優(yōu)選實(shí)現(xiàn)中,后面的響應(yīng)也被以XML編碼,并包含具有時(shí)間編碼以精確地捕獲被遠(yuǎn)程執(zhí)行的流的原始SOAP包封。在一個(gè)實(shí)施例中,Web服務(wù)流順序執(zhí)行(如在圖14中的封裝體中所示)。單個(gè)記錄1401向求和圖標(biāo)1402提供信息,然后向均值圖標(biāo)1403并最終向中值圖標(biāo)1404提供信息,并且由結(jié)果圖標(biāo)1405提供結(jié)果。每個(gè)圖標(biāo)均被個(gè)性化以執(zhí)行所需的功能,包括“null”,其將記錄傳遞到下一個(gè)階段。在一個(gè)實(shí)施例中,Web服務(wù)流并行地執(zhí)行。此功能由封裝體修改器提供。在一個(gè)實(shí)施例中,提供一并行執(zhí)行修改器(圖14)。給定單個(gè)Web服務(wù)調(diào)用1501,隨后可有多條并行路徑。然后在1505,或者通過另一個(gè)Web服務(wù)調(diào)用/封裝體或者經(jīng)由一數(shù)據(jù)規(guī)范器來吸收一個(gè)或多個(gè)路徑的結(jié)果。數(shù)據(jù)規(guī)范器獲取多個(gè)數(shù)據(jù)輸入并以可用的方式格式化該數(shù)據(jù)。例如,如果求一組數(shù)據(jù)的和1502、中值1504和均值1503,并且并行計(jì)算,一優(yōu)選的規(guī)范器1505可被配置為僅存儲(chǔ)最低值。在另一個(gè)實(shí)施例中,來自所有路徑的結(jié)果1506被存儲(chǔ),作為該服務(wù)調(diào)用的最終值。在一優(yōu)選實(shí)現(xiàn)中,該結(jié)果1506為一XML文檔,其代表由封裝體流的結(jié)果定義的數(shù)據(jù)結(jié)構(gòu)。在一優(yōu)選實(shí)現(xiàn)中,任何上述修改器中遵循由封裝體環(huán)境提供的其他窗口小部件的模式,例如報(bào)警對(duì)話框。更復(fù)雜的流可能包括并行功能(圖15)。圖15示出在同一組數(shù)據(jù)上執(zhí)行的一組統(tǒng)計(jì)操作。在此情況下,求和、中值和均值是打算在單獨(dú)一組數(shù)據(jù)上運(yùn)行的單獨(dú)的Web服務(wù)。該數(shù)據(jù)沒有改變,并且來自一個(gè)服務(wù)的輸出不作為輸入流入另一個(gè)服務(wù)。該封裝體已被安排為并行執(zhí)行Web服務(wù)。這通過將初始輸入連接到每個(gè)服務(wù)上來實(shí)現(xiàn)。其結(jié)果是合并功能的輸入,該合并功能使數(shù)據(jù)相結(jié)合。并行執(zhí)行可優(yōu)化封裝體的總性能。在一個(gè)實(shí)施例中,通過使用GUI顯示指點(diǎn)設(shè)備例如鼠標(biāo)畫出互連線來使圖標(biāo)互連。在另一個(gè)實(shí)施例中,通過在顯示工具欄上選擇互連功能或利用每個(gè)圖標(biāo)具有的手段,來使圖標(biāo)互連。在一個(gè)實(shí)施例中,使用一修改器塊1506。在圖15的示例中,修改器塊是被拖到封裝體中的圖標(biāo)。第一圖標(biāo)1501連接到該塊的輸入A,該塊的輸出C、D和E連接到它們各自的塊1502-1504。這種塊可具有多個(gè)輸入和多個(gè)輸出。該塊可具有預(yù)定的功能(互連),或者可以是實(shí)現(xiàn)轉(zhuǎn)換、過濾、監(jiān)控或除了流互連之外的任意多個(gè)有用服務(wù)的功能圖標(biāo)。用戶可在適當(dāng)時(shí)拖放多個(gè)服務(wù)圖標(biāo),并使起始輸入連接到多個(gè)分支。使用數(shù)據(jù)合并修改器或其他Web服務(wù)封裝體,可將該些分支的輸入合并成單個(gè)結(jié)果。在一個(gè)實(shí)施例中,此結(jié)果為一XML。當(dāng)需要在相同或不同的數(shù)據(jù)集上執(zhí)行多個(gè)操作時(shí),可獲得進(jìn)一步的功能分配。圖16示出使多組數(shù)據(jù)需要同樣的統(tǒng)計(jì)生成的解決方案。因?yàn)閿?shù)據(jù)集的數(shù)量大于1,所以流可利用其他封裝體服務(wù)器以執(zhí)行最初的并行查詢。這利用了封裝體流中的并行功能,但是也將服務(wù)封裝體執(zhí)行分配到多個(gè)封裝體服務(wù)器上。在另一個(gè)實(shí)施例中,執(zhí)行的Web服務(wù)流帶有開關(guān)功能。此功能由封裝體修改器提供。在一個(gè)實(shí)施例圖18中,提供了開關(guān)修改器1802。該開關(guān)修改器1802檢查給定變量或事件的狀態(tài),以確定在哪個(gè)路徑上繼續(xù)執(zhí)行。例如,Web服務(wù)調(diào)用的結(jié)果是三個(gè)不同值之一。根據(jù)此調(diào)用的值將遵循不同的執(zhí)行路徑。例如,結(jié)果A分支到第一路徑,結(jié)果B分支到第二路徑而結(jié)果C轉(zhuǎn)到第三路徑。還存在其他的可能性,并且本發(fā)明決不是由此示例限制。在圖18的示例中,將記錄1801提供給開關(guān)1802,該開關(guān)確定是否執(zhí)行作圖或求和操作。此開關(guān)然后根據(jù)開關(guān)1802的個(gè)性化,來將消息發(fā)送給求和圖標(biāo)1803或作標(biāo)1804(或這兩個(gè)圖標(biāo))。在1805,合并且報(bào)告該結(jié)果。開關(guān)功能提供了另一種根據(jù)流的值或狀態(tài)控制封裝體的分支的方法(圖18)。給定另一個(gè)統(tǒng)計(jì)示例,可使輸入的請求指示數(shù)據(jù)的求和或圖形表示。使用該開關(guān)修改器,提供了一種與其中執(zhí)行每個(gè)路徑的并行功能不同的分支機(jī)制。開關(guān)提供了能夠返回多個(gè)結(jié)果的單個(gè)封裝體。此外,其使得流設(shè)計(jì)者能夠在存在特定條件的情況下執(zhí)行不同的分支。例如,封裝體設(shè)計(jì)者可決定應(yīng)根據(jù)一天中的時(shí)間來執(zhí)行不同的分支。封裝體設(shè)計(jì)者生成它們的流,并使用開關(guān)修改器來連接它們??稍O(shè)定封裝體修改器中的條件以檢測時(shí)間為AM還是PM。根據(jù)其結(jié)果,執(zhí)行分支中的一個(gè)。該示例是一個(gè)簡單化的示例,但是說明了該開關(guān)可由任意數(shù)量的事件、其他封裝體的輸出、時(shí)間以及作為執(zhí)行的一部分傳遞的參數(shù)觸發(fā)這一點(diǎn)。在另一個(gè)實(shí)施例圖16中,記錄1601可與在另一條路徑中順序執(zhí)行(求和1612、均值1613,然后中值1614)的其他記錄并行地由任何一條路徑順序執(zhí)行(求和1602、均值1603,然后中值1604)。在另一個(gè)實(shí)施例中,通過向并行圖標(biāo)1702、1703、1704提供多條互連線來指示記錄1701的并行執(zhí)行,并且通過將該些并行圖標(biāo)的輸出提供給結(jié)果圖標(biāo)1705來合并1705該結(jié)果。盡管已示出和說明了本發(fā)明的優(yōu)選實(shí)施例,但是應(yīng)理解,本發(fā)明并不局限于文中所公開的準(zhǔn)確結(jié)構(gòu),并且“保留”在所附權(quán)利要求限定的本發(fā)明的范圍內(nèi)進(jìn)行一切改變和修改的權(quán)利。附錄//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.awt.Point;importjava.io.Serializable;/***該類提供了Web服務(wù)的構(gòu)件塊的基本實(shí)現(xiàn)。*/publicabstractclassBlockextendsObjectimplementsSerializable{ intx; inty; LinkoutLink; booleanrunning=false; finalstaticintmarginLeft=6; finalstaticintmarginTop=3; /** *構(gòu)造函數(shù) */ publicBlock(){ } publicvoidsetLoc(intx,inty){ this.x=x; this.y=y(tǒng); }<!--SIPO<DPn="20">--><dpn="d20"/> publicintgetX(){ returnthis.x; } publicintgetY(){ returnthis.y; } publicLinkgetOutLink(){ returnthis.outLink; } publicvoidsetOutLink(Linklink){ this.outLink=link; } publicvoidsetRunning(booleanvalue){ this.running=value; } publicabstractPointgetOutPoint(); publicabstractPointgetInPoint(intindex); publicabstractbooleanisDragingTitle(intposX,intposY); publicabstractbooleanisDragingOutput(intposX,intposY); publicabstractObjectexecute();}//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjavax.swing.*;importjavax.swing.event.*;<!--SIPO<DPn="21">--><dpn="d21"/>importjavax.swing.plaf.metal.*;importjavax.swing.tree.*;importjava.awt.*;importjava.awt.datatransfer.*;importjava.awt.dnd.*;importjava.awt.dnd.peer.*;importjava.awt.event.*;importjava.io.*;/***該類提供了可從其拖出服務(wù)對(duì)象的樹組件。*/publicclassDragTree extendsJTree implementsTreeSelectionListener,DragGestureListener,DragSourceListener{/**存儲(chǔ)組件的父框架*/privateWorkFrameparent=null;/**存儲(chǔ)選擇的節(jié)點(diǎn)信息*/protectedTreePathSelectedTreePath=null;protectedDefaultMutableTreeNodeSelectedNode=null;/**拖動(dòng)所需變量*/privateDragSourcedragSource=null;privateDragSourceContextdragSourceContext=null;<!--SIPO<DPn="22">--><dpn="d22"/> privatePointcursorLocation=null; /**構(gòu)造函數(shù) @paramroot樹的根節(jié)點(diǎn) @paramparentJTree的父JFrame*/ publicDragTree(DefaultTreeModeltreemodel,WorkFrameparent){ super(treemodel); this.parent=parent; addTreeSelectionListener(this); dragSource=DragSource.getDefaultDragSource(); DragGestureRecognizerdgr=dragSource.createDefaultDragGestureRecognizer(this,//DragSource DnDConstants.ACTION_COPY_OR_MOVE,//指定合法動(dòng)作 this//DragGestureListener); /*取消鼠標(biāo)右鍵點(diǎn)擊作為合法動(dòng)作-如果為JTree實(shí)現(xiàn)了 *JPopupMenu,則特別有用 */ dgr.setSourceActions(dgr.getSourceActions()&~I(xiàn)nputEyent.BUTTON3_MASK); //不必要,但給出了文件管理器的外觀 putClientProperty(″JTree.lineStyle″,″Angled″); //MetalTreeUIui=(MetalTreeUI)getUI();) } /**返回所選節(jié)點(diǎn)*/ publicDefaultMutableTreeNodegetSelectedNode(){ returnSelectedNode; }<!--SIPO<DPn="23">--><dpn="d23"/> /////////////////////////接口代碼//////////////////// /**DragGestureListener接口方法*/ publicvoiddragGestureRecognized(DragGestureEvente){ //獲得所選節(jié)點(diǎn) DefaultMutableTreeNodedragNode=getSelectedNode(); if(dragNode?。絥ull&&dragNode.isLeaf()){ //獲得Transferable對(duì)象 Transferabletransferable=(Operation)dragNode.getUserObject(); try{ ((FlowPane)parent.getSelectedFrame().getContentPane()).setOutsiderDrop(true); }catch(java.lang.NullPointerExceptionne){ System.out.println(″nointernalframe,notdragged″); } //開始拖動(dòng) dragSource.startDrag(e,DragSource.DefaultCopyDrop,transferable,this); }else{ System.out.println(″notleaf,notdragged″);} } /**DragSourceListener接口方法*/ publicvoiddragDropEnd(DragSourceDropEventdsde){ } /**DragSourceListener接口方法*/ publicvoiddragEnter(DragSourceDragEventdsde){<!--SIPO<DPn="24">--><dpn="d24"/> setCursor(dsde); } /**DragSourceListener接口方法*/ publicvoiddragOver(DragSourceDragEventdsde){ setCursor(dsde); } /**DragSourceListener接口方法*/ publicvoiddropActionChanged(DragSourceDragEventdsde){ } /**DragSourceListener接口方法*/ publicvoiddragExit(DragSourceEventdsde){ } /**DragSourceListener接口方法。這有點(diǎn)難看。這是根據(jù)是否允許 *放Transferable對(duì)象而設(shè)置光標(biāo)的地方。然而,需要有鼠標(biāo)的位 *置和設(shè)置光標(biāo)的對(duì)象,這兩者來自兩個(gè)不同的事件。盡管它不漂 *亮,但使用DropTargetListenerdragOver方法中的位置設(shè)置一 *全局變量。 */ voidsetCursor(DragSourceDragEventdsde){ /*//如果不知道光標(biāo)位置,則什么也不做?! f(cursorLocation==null)return; TreePathdestinationPath=getPathForLocation(cursorLocation.x,cursorLocation.y); //獲得設(shè)置鼠標(biāo)類型的對(duì)象<!--SIPO<DPn="25">--><dpn="d25"/> DragSourceContextdsc=dsde.getDragSourceContext(); //如果目標(biāo)路徑可行,則設(shè)置光標(biāo)以允許放... if(testDropTarget(destinationPath,SelectedTreePath)==null) dsc.setCursor(DragSource.DefaultCopyDrop); //...否則設(shè)置不允許放 elsedsc.setCursor(DragSource.DefaultCopyNoDrop); */ } /**TreeSelectionListener-設(shè)置所選節(jié)點(diǎn)*/ publicvoidvalueChanged(TreeSelectionEventevt){ SelectedTreePath=evt.getNewLeadSelectionPath(); if(SelectedTreePath==null){ SelectedNode=null; return; } SelectedNode=(DefaultMutableTreeNode)SelectedTreePath.getLastPathComponent(); }}//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.awt.*;importjava.awt.datatransfer.*;importjava.awt.dnd.*;importjava.awt.dnd.peer.*;<!--SIPO<DPn="26">--><dpn="d26"/>importjava.awt.event.*;importjavax.swing.ImageIcon;importjavax.swing.*;importjava.io.*;importjava.util.*;/***該類實(shí)現(xiàn)用戶可在其中拖放Web服務(wù)對(duì)象或設(shè)置Web服務(wù)對(duì)象的屬*性的工作區(qū)。*/publicclassFlowPaneextendsContainer implementsDropTargetListener, DragGestureListener, DragSourceListener, ActionListener/*,鼠標(biāo)偵聽器*/{ JPopupMenupopupDelOp=newJPopupMenu(); JPopupMenupopupSetDelOp=newJPopupMenu(); JPopupMenupopupDelLink=newJPopupMenu(); JPopupMenupopupFilter=newJPopupMenu(); JPopupMenupopupPresenter=newJPopupMenu(); JMenuItemitemSet; JMenuItemitemSetDelOp; JMenuItemitemDeleteOp; JMenuItemitemDeleteLink; JMenuItemitemView; JMenuItemitemFilterDelete; JMenuItemitemFilterSet; JMenuItemitemFilterView; JMenuItemitemPresenterDel;<!--SIPO<DPn="27">--><dpn="d27"/> WorkFrameworkFrame; WorkFlowFrameflowFrame; WorkFlowworkflow; booleanoutsiderDrop=true;//如果從左側(cè)樹拖動(dòng) booleanmovingDrop;//如果標(biāo)題欄被拖動(dòng)則為真 intdragFromX,dragFromY; /**拖動(dòng)所需變量*/ privateDragSourcedragSource=null; privateDragSourceContextdragSourceContext=null; /** *構(gòu)造函數(shù) */ publicFlowPane(WorkFrameworkFrame, WorkFlowFrameflowFrame, WorkFlowworkflow){ DropTargetdropTarget=newDropTarget(this,this); this.workFrame=workFrame; this.flowFrame=flowFrame; this.workflow=workflow; this.workflow.setContainer(this); this.setBackground(Color.white); dragSource=DragSource.getDefaultDragSource(); DragGestureRecognizerdgr=dragSource.createDefaultDragGestureRecognizer(this,//DragSource DnDConstants.ACTIONMOVE,//指定合法操作<!--SIPO<DPn="28">--><dpn="d28"/> this//DragGestureListener ); createPopupMenu(); addMouseListener(newMouseAdapter(){ publicvoidmousePressed(MouseEvente){ checkForTriggerEvent(e); } publicvoidmouseReleased(MouseEvente){ checkForTriggerEvent(e); } });}voidsetWorkflow(WorkFlowworkflow){ this.workflow=workflow; workflow.setContainer(this);}WorkFramegetWorkFrame(){returnthis.workFrame;}voidcreatePopupMenu(){ popupSetDelOp.add(itemSet=newJMenuItem(″設(shè)置值″)); itemSet.addActionListener(this); popupSetDelOp.addSeparator(); popupSetDelOp.add(itemSetDelOp=newJMenuItem(″刪除″)); popupSetDelOp.addSeparator();<!--SIPO<DPn="29">--><dpn="d29"/> itemSetDelOp.addActionListener(this); popupSetDelOp.add(itemView=newJMenuItem(″視圖″)); itemView.addActionListener(this); popupSetDelOp.setInvoker(this); popupDelOp.add(itemDeleteOp=newJMenuItem(″刪除″)); itemDeleteOp.addActionListener(this); popupDelLink.add(itemDeleteLink=newJMenuItem(″刪除″)); itemDeleteLink.addActionListener(this); popupDelLink.setInvoker(this); popupFilter.add(itemFilterDelete=newJMenuItem(″刪除過濾器″)); itemFilterDelete.addActionListener(this); popupFilter.setInvoker(this); popupFilter.add(itemFilterSet=newJMenuItem(″設(shè)置過濾器″)); itemFilterSet.addActionListener(this); popupFilter.setInvoker(this); popupFilter.add(itemFilterView=newJMenuItem(″查看過濾器″)); itemFilterView.addActionListener(this); popupFilter.setInvoker(this); popupPresenter.add(itemPresenterDel=newJMenuItem(″Delete″)); itemPresenterDel.addActionListener(this); popupPresenter.setInvoker(this); } voidcheckForTriggerEvent(MouseEvente){<!--SIPO<DPn="30">--><dpn="d30"/> //獲得所選操作 if(e.isPopupTrigger()){ Blockblock=workflow.Select(e.getX(),e.get); if(block!=null){ if(blockinstanceofOperation){ Operationoper=(Operation)block; if(oper.isDragingTitle(e.getX(),e.getY()) ‖oper.isDragingOutput(e.getX(),e.getY())){ popupDelOp.show(e.getComponent(),e.getX(),e.getY()); return; }else{ intindex=oper.selectlnput(e.getY()); if((index>=0) &&(oper.getInLink(index)==null) &&oper.isSetable(index)){ workflow.setSelectedIndex(index); popupSetDelOp.show(e.getComponent(),ee.getX(),e.getY()); return; } } }//blockinstanceofOperation結(jié)束 elseif(blockinstanceofXMLFilter){ popupFilter.show(e.getComponent(),e.getX(),e.getY()); return; }<!--SIPO<DPn="31">--><dpn="d31"/> elseif(blockinstanceofPresenter){ popupPresenter.show(e.getComponent(),e.getX(),e.getY()); return; } }//ifblock?。絥ull結(jié)束 else{//檢查是否選擇了一連接 Linklink=workflow.selectLink(e.getX(),e.getY()); if(link′=null){ popupDelLink.show(e.getComponent(),e.getX(),e.getY()); return; } } } } /**DropTaregetListener接口方法*/ publicvoiddragEnter(DropTargetDragEvente){ //System.out.println(″dragenter′); } /**DropTaregetListener接口方法*/ publicvoiddragExit(DropTargetEvente){ //System.out.println(″dragexit″); } /**DropTaregetListener接口方法*/<!--SIPO<DPn="32">--><dpn="d32"/> publicvoiddragOver(DropTargetDragEvente){ //設(shè)置光標(biāo)位置。setCursor方法中需要 } /**DropTaregetListener接口方法*/ publicvoiddropActionChanged(DropTargetDragEvente){ } /**DropTargetListener接口方法-釋放拖動(dòng)時(shí)做什么*/ publicvoiddrop(DropTargetDropEvente){ //只放在具有焦點(diǎn)的內(nèi)部框架上 if(!this.flowFrame.isSelected()){ e.rejectDrop(); //System.out.println(″Rejectdropbecauseframenot<br/>selected″); return; } //獲得transferable //System.out.println(″dropat″+e.getLocation().x+″,″+e.getLocation().y); Transferabletr=e.getTransferable(); //不支持flavor,拒絕放 if(!tr.isDataFlavorSupported(Operation.OPERATION_FLAVOR)&&!tr.isDataFlavorSupported(XMLFilter.XMLFILTER_FLAVOR)&&!tr.isDataFlavorSupported(Presenter.PRESENTERFLAVOR)){ e.rejectDrop(); //System.out.println(″Rejectdropbecauseofnotsupportedflavor″);<!--SIPO<DPn="33">--><dpn="d33"/> }else{ e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); //System.out.println(″acceptdrop″); } BlockdragedBlock=null; if(tr.isDataFlavorSupported(operation.OPERATION_FLAVOR)){ //轉(zhuǎn)換到適當(dāng)?shù)臄?shù)據(jù)類型 try{ dragedBlock=(Operation)tr.getTransferData(Operation.OPERATION_FLAVOR); }catch(Exceptionexc){ exc.printStackTrace(); e.dropComplete(true); return; } //System.out.println(″dragedOperation=″+dragedOper); //獲得新位置 Pointloc=e.getLocation(); //獲得節(jié)點(diǎn) //Operationoper=(Operation)workFrame.getTree().getSelectedNode().getUserObject(); //System.out.println(″selectedNode=″+oper.toString()); if(outsiderDrop){ //System.out.println(″outsiderDrop″); workflow.addOperation((Operation)dragedBlock,e.getLocation().x,e.getLocation().y); }else{<!--SIPO<DPn="34">--><dpn="d34"/> if(movingDrop){ //System.out.println(″moveto″+e.getLocation().x+″,″+e.getLocation().y); workflow.moveOperation( e.getLocation().x-dragFromX, e.getLocation().y-dragFromY); }else{ Stringmsg=workflow.addOperationLink(e.getLocation().x,e.getLocation().y); if(msg?。絥ull) JOptionPane.showMessageDialog(this,msg); } } //適當(dāng)展開節(jié)點(diǎn)-可能這不是最好的方法... }elseif(tr.isDataFlavorSupported(XMLFilter.XMLFILTER_FLAVOR)){ try{ //轉(zhuǎn)換到適當(dāng)?shù)臄?shù)據(jù)類型 dragedBlock=(XMLFilter)tr.getTransferData(XMLFilter.XMLFILTER_FLAVOR); }catch(Exceptionexc){ exc.printStackTrace(); e.dropComplete(true); return; } //System.out.println(″dragedFilter=″+dragedBlock); //獲得新位置 Pointloc=e.getLocation();<!--SIPO<DPn="35">--><dpn="d35"/> if(outsiderDrop){ //System.out.println(″outsiderDrop″); workflow.addFilter((XMLFilter)dragedBlock,e.getLocation().x,e.getLocation().y); }else{ if(movingDrop){ workflow.moveFilter( e.getLocation().x-dragFromX, e.getLocation().y-dragFromY); }else{ Stringmsg=workflow.addFilterLink(e.getLocation().x,e.getLocation().y); if(msg?。絥ull) JOptionPane.showMessageDialog(this,msg); } } }elseif(tr.isDataFlavorSupported(Presenter.PRESENTER_FLAVOR)){ try{ //轉(zhuǎn)換到適當(dāng)?shù)臄?shù)據(jù)類型 dragedBlock=(Presenter)tr.getTransferData(Presenter.PRESENTER_FLAVOR); }catch(Exceptionexc){ exc.printStackTrace(); e.dropComplete(true); return; } //System.out.println(″dragedFilter=″+dragedBlock);<!--SIPO<DPn="36">--><dpn="d36"/> //獲得新位置 Pointloc=e.getLocation(); if(outsiderDrop){ if(workflow.getPresenter()?。絥ull) JOptionPane.showMessageDialog(this,″Cannotaddmorethanonepresenter!″,null,JOptionPane.WARNING_MESSAGE); else{workflow.setPresenter((Presenter)dragedBlock,e.getLocation().x,e.getLocation().y); //System.out.println(″workflowsetpresenter″); } }else{ if(movingDrop){ workflow.movePresenter(e.getLocation().x-dragFromX,e.getLocation().y-dragFromY); } } } this.repaint(); e.dropComplete(true); //System.out.println(″dropcomplete″); }//方法結(jié)束 publicvoidpaint(Graphicsg){ super.paint(g); Vectoropers=workflow.getOperationVec(); for(inti=0;i<o(jì)pers.size();i++){ ((Operation)(opers.elementAt(i))).draw(g); }<!--SIPO<DPn="37">--><dpn="d37"/> Vectorlinks=workflow.getLinkVec(); for(inti=0;i<links.size();i++){ ((Link)(links.elementAt(i))).draw(g); } Vectorfilters=workflow.getFilterVec(); for(inti=0;i<filters.size();i++){ ((XMLFilter)(filters.elementAt(i))).draw(g); } if(workflow.getPresenter()!=null){ /*Imageimage=Toolkit.getDefaultToolkit().createImage(workflow.getPresenter()..getIconFileName()); g.drawImage(image, workflow.getPresenterl).getXI), workflow.getPresenter().getY(), this);*///System.out.println(″drawpresenter″); Presenterpresenter=workflow.getPresenter(); Stringtype=presenter.getType(); //g.drawRect(workflow.getPresenter().getX(),workflow.getPresenter().getY(),16,16); if(type.equals(″Text″)) g.drawImage(this.workFrame.textImage,presenter.getX(),presenter.getY(),presenter.recW,presenter.recH,this); elseif(type.equals(″Image″)) g.drawImage(this.workFrame.imageImage,presenter.getX(),presenter.getY(),presenter.recW,presenter.recH,this); elseif(type.equals(″Sound″))<!--SIPO<DPn="38">--><dpn="d38"/> g.drawImage(this.workFrame.soundImage,presenter.getX(),presenter.getY(),presenter.recW,presenter.recH,this); } } ///////拖動(dòng)代碼///////////////////// /**DragGestureListener接口方法*/ publicvoiddragGestureRecognized(DragGestureEvente){ //獲得所選操作 Blockblock=workflow.select(e.getDragOrigin().x,e.getDragOrigin().y); if(block?。絥ull){ setOutsiderDrop(false); if(block.isDragingTitle(e.getDragOrigin().x,e.getDragOriginO.y)){//移動(dòng)框 movingDrop=true; dragFromX=e.getDragOrigin().x; dragFromY=e.getDragOrigin().y; //開始拖動(dòng) if(blockinstanceofOperation) dragSource.startDrag(e,DragSource.DefaultMoveDrop,(Operation)block,this); elseif(blockinstanceofXMLFilter) dragSource.startDrag(e,DragSource.DefaultMoveDrop,(XMLFilter)block,this); elseif(blockinstanceofPresenter) dragSource.startDrag(e,DragSource.DefaultMoveDrop,(Presenter)block,this);<!--SIPO<DPn="39">--><dpn="d39"/> }else{ //ImageIconicon=newImageIcon(″images\\item.jpg″); if(block.isDragingOutput(e.getDragOrigin().x,e.getDragOrigin().y)){ movingDrop=false; if(blockinstanceofOperation) dragSource.startDrag(e,DragSource.DefaultMoveDrop,(Operation)block,this); elseif(blockinstanceofXMLFilter) dragSource.startDrag(e,DragSource.DefaultMoveDrop,(XMLFilter)block,this); } } } } /**DragSourceListener接口方法*/ publicvoiddragDropEnd(DragSourceDropEventdsde){ } /**DragSourceListener接口方法*/ publicvoiddragEnter(DragSourceDragEventdsde){ } /**DragSourceListener接口方法*/ publicvoiddragOver(DragSourceDragEventdsde){ }<!--SIPO<DPn="40">--><dpn="d40"/>/**DragSourceListener接口方法*/publicvoiddropActionChanged(DragSourceDragEventdsde){}/**DragSourceListener接口方法*/publicvoiddragExit(DragSourceEventdsde){}publicvoidsetOutsiderDrop(booleanflag){ outsiderDrop=flag;}////鼠標(biāo)偵聽器///////*publicvoidmouseClicked(MouseEvente){ workflow.mouseClicked(e.getX(),e.getYl)); this.repaint();}publicvoidmousePressed(MouseEvente){}publicvoidmouseReleased(MouseEvente){}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}*/<!--SIPO<DPn="41">--><dpn="d41"/> publicvoidactionPerformed(ActionEvente){ //確定選擇了哪個(gè)菜單項(xiàng) if(e.getSource==itemDeleteLink){ workflow.deleteLink(); }elseif(e.getSource()=-itemDeleteOp){ workflow.deleteOpo; }elseif(e.getSouree()==itemSet){ Stringinput=JOptionPane.showInternalInputDialog(this,″Setvaluefor″+workflow.selectedOperation.getParamName(workflow.selectedIndex),″Input″,JOptionPane.INFORMATIONMESSAGE); if(input?。絥ull) workflow.selectedOperation.setParamValue(input,workflow.selectedIndex); }elseif(e.getSource==itemSetDelOp){workflow.selectedOperation.delParamValue(workflow.selectedIndex); }elseif(e.getSource==itemView){ JOptionPane.showInternalMessageDialog( this,workflow.selectedOperation.getParamValue(workflow.selectedIndex),″Valueof″+workflow.selectedOperation.getParamName(workflow.selectedIndex),JOptionPane.INFORMATIONMESSAGE); }elseif(e.getSource==itemFilterDelete){ workflow.deleteFilter(); }elseif(e.getSource==itemFilterSet){ Stringinput=JOptionPane.showInternalInputDialog( this,<!--SIPO<DPn="42">--><dpn="d42"/>″Setfilter″,″Input″,JOptionPane.INFORMATION_MESSAGE);if(input?。絥ull)workflow.selectedFilter.setXmlpath(input);}elseif(e.getSource==itemFilterView){JOptionPane.showInternalMessageDialog(this,workflow.selectedFilter.getXmlpath(),″FilterValue″,JOptionPane.INFORMATIONMESSAGE);}elseif(e.getSource==itemPresenterDel){workflow.deletePresenter();}repaint();}}//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.io.*;importjava.awt.*;/***該類實(shí)現(xiàn)在Web服務(wù)對(duì)象間的連接組件。*/publicclassLinkextendsObjectimplementsSerializable{BlockfromBlock;<!--SIPO<DPn="43">--><dpn="d43"/>BlocktoBlock;//Presenterpresenter;inttoIndex;booleanrunning=false;staticfinalintrange=5;staticfinalintARROW_SIDE=8;//箭頭大小staticfinalintARROW_HEIGHT=10;/***構(gòu)造函數(shù)*/publicLink(Operationfrom,Operationto,inttolndex){this.fromBlock=from; this.toBlock=to; this.toIndex=toIndex;}publicLink(Operationfrom,XMLFilterto){ this.fromBlock=from; this.toBlock=to; this.toIndex=-1;}publicLink(XMLFilterfrom,Operationto,inttoIndex){ this.fromBlock=from; this.toBlock=to; this.toIndex=toIndex;<!--SIPO<DPn="44">--><dpn="d44"/> } publicLink(Operationfrom,Presenterpresenter){ this.fromBlock=from; //this.presenter=presenter; this.toBlock=presenter; this.tolndex=-1; } publicLink(XMLFilterfilter,Presenterpresenter){ this.fromBlock=filter; //this.presenter=presenter; this.toBlock=presenter; this.toIndex=-1; } publicvoiddraw(Graphicsg){ if(running) g.setColor(Color.green); //if(presenter==null){ g.drawLine(fromBlock.getOutPoint().x,fromBlock.getOutPoint().y,toBlock.getInPoint(toIndex).x,toBlock.getInPoint(toIndex).y); this.drawArrow(g,fromBlock.getOutPoint(),toBlock.getInPoint(toIndex)); /*}else{ g.drawLine(fromBlock.getOutPoint().x,fromBlock.getOutPoint().y,presenter.getInPoint().x,presenter.getInPoint<!--SIPO<DPn="45">--><dpn="d45"/>(toIndex).y); this.drawArrow(g,fromBlock.getOutPoint(),presenter.getInPoint()); }*/ g.setColor(Color.black);}/*publicLinkselect(intposX,intposY){ finaldoublecoef=1.01; intx1=fromBlock.getOutPoint().x; inty1=fromBlock.getOutPoint().y; intx2=toBlock.getOutPoint().x; inty2=toBlock.getOutPoint().y; doublelength=Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)); doubled1=Math.sqrt(Math.pow((posX-x1),2)+Math.pow((posY-y1),2)); doubled2=Math.sqrt(Math.pow((posX-x1),2)+Math.pow((posY-y1),2)); if((d1+d2)<length*coef) returnthis; elsereturnnull;}*/publicLinkselect(intpx,intpy){ intx1=fromBlock.getOutPoint().x; inty1=fromBlock.getOutPoint().y; //intx2=<!--SIPO<DPn="46">--><dpn="d46"/>(toBlock?。絥ull)?toBlock.getInPoint(toIndex).xpresenter.getInPoint().x; //inty2=(toBlock?。絥ull)?toBlock.getInPoint(toIndex).ypresenter.getInPoint().y; intx2=toBlock.getInPoint(toIndex).x; inty2=toBlock.getInPoint(toIndex).y; //處理x1=x2時(shí)的情況 if(x1==x2){ if(py>=Math.min(y1,y2)&&py<=Math.max(y1,y2)&&Math.abs(px-x1)<=range) returnthis; elsereturnnull; }elseif(y1=y(tǒng)2){ if(px>=Math.min(x1,x2)&&px<=Math.max(x1,x2)&&Math.abs(py-y1)<=range) returnthis; elsereturnnull; }else{ doubleslope=(double)(y2-y1)/(x2-x1); doubleix=(slope*py-slope*y1+slope*slope*x1+px)/(slope*slope+1); doubleiy=y(tǒng)1+slope*(ix-x1); doubled=Math.sqrt(Math.pow((px-ix),2)+Math.pow((py-iy),2)); if(ix>=Math.min(x1,x2)&&ix<=Math.max(x1,x2)&&drange) returnthis; else{ /*System.out.println(″Theslopeis″+slope);<!--SIPO<DPn="47">--><dpn="d47"/> System.out.println(″Thefirstpointis″+x1+″,″+y1); System.out.println(″Thesecondpointis″+x2+″,″+y2); System.out.println(″Thepointis″+px+″,″+py); System.out.println(″Theintersectionis(x,y)″+ix+″,″+iy); System.out.println(″distanceis″+d); System.out.println(″therangeis″+range);*/ returnnull; } } } publicBlockgetFromBlock(){ returnthis.fromBlock; } publicBlockgetToBlock(){ returnthis.toBlock; } /*publicPresentergetPresenter(){ returnthis.presenter; } */ publicintgetToIndex(){ returntoIndex;<!--SIPO<DPn="48">--><dpn="d48"/>}publicvoidsetRunning(booleanvalue){ this.running=value;}/***從點(diǎn)pFrom到點(diǎn)pTo繪制箭頭。*/privatevoiddrawArrow(Graphicsg,PointpFrom,PointpTo){ doubleslope; intborderSpace=2; doublefx,fy,tx,ty; /*(x1,y1)(centerX,centerY)左邊的點(diǎn)*/ /*(x2,y2)(centerX,centerY)右邊的點(diǎn)*/ doublex1,y1,x2,y2; doublecenterX=0; doublecenterY=0; doubledistance; fx=pFrom.getX(); fy=pFrom.getY(); tx=pTo.getX(); ty=pTo.getY(); distance=Math.sqrt(Math.pow(fx-tx,2)+Math.pow(fy-ty,2)); if(distance<=borderSpace)return; if(tx==fx){//重直線,斜率將為無限大, centerX=tx;//中點(diǎn)具有與pFrom、pTo相同的x?! f(ty>=fy)//箭頭向下。<!--SIPO<DPn="49">--><dpn="d49"/> centerY=ty-ARROW_HEIGHT; else//箭頭向上?! enterY=ty+ARROW_HEIGHT; y1=centerY; y2=centerY; x1=centerX-(int)ARROW_SIDE/2; x2=centerX+(int)ARROW_SIDE/2; }elseif(ty==fy){//水平線?! enterY=ty;//中點(diǎn)具有與pFrom、pTo相同的y。 if(tx>=fx)//箭頭向右?! enterX=tx-ARROW_HEIGHT; else//箭頭向左?! enterX=tx+ARROW_HEIGHT; x1=centerX; x2=centerX; y1=centerY-(int)ARROW_SIDE/2; y2=centerY+(int)ARROW_SIDE/2; }else{ //線的斜率 slope=(pTo.getY()-pFrom.getY())/(pTo.getX()-pFrom.getX()); //箭頭部的斜率 slope=-1/slope; centerX=tx+ARROW_HEIGHT*(fx-tx)/distance; centerY=ty+ARROW_HEIGHT*(fy-ty)/distance; x1=centerX+ARROW_SIDE/Math.sqrt(l+slope*slope)/2; x2=centerX-ARROW_SIDE/Math.sqrt(l+slope*slope)/2; y1=centerY+ARROW_SIDE/Math.sqrt(l+slope*slope)<!--SIPO<DPn="50">--><dpn="d50"/>*slope/2;y2=centerY-ARROW_SIDE/Math.sqrt(l+slope*slope)*slope/2;}intxPoints[]={(int)x1,(int)tx,(int)x2};intyPoints[]={(int)y1,(int)ty,(int)y2};g.fillPolygon(xPoints,yPoints,3);g.drawLine((int)fx,(int)fy,(int)tx,(int)ty);}}//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.awt.datatransfer.*;importjava.util.*;importjava.io.*;importjava.awt.*;importjava.awt.geom.*;importjava.awt.geom.Rectangle2D.Double;importorg.apache.soap.*;importorg.apache.soap.rpc.*;importorg.apache.soap.transport.http.*;importorg.w3c.dom.*;importorg.apache.xerces.parsers.*;importorg.xml.sax.*;<!--SIPO<DPn="51">--><dpn="d51"/>importjava.io.*;importjava.net.*;/***該類提供了Web服務(wù)方法調(diào)用的表示。*/publicclassOperationextendsBlock//Object implementsTransferable,Serializable{ finalpublicstaticDataFlavorOPERATION_FLAVOR=newDataFlavor(Operation.class,″OperationInformation″); staticDataFlavorflavors[]={OPERATION_FLAVOR}; intwidth; intheight; staticintrecH; Serviceservice; StringserviceName; Strjngname; StringparamTypes[]; StringparamNames[]; ObjectparamValues[]; LinkinLink[]; StringreturnName; StringreturnType; ObjectreturnValue; /*intx;<!--SIPO<DPn="52">--><dpn="d52"/> inty; intwidth; intheight; staticintrecH; finalstaticintmarginLeft=3; finalstaticintmarginTop=3; */ finalstaticintconnectorW=6; finalstaticintconnectorH=6; /** *構(gòu)造函數(shù) */ publicOperation(){ } publicOperation(Serviceservice,Stringname,StringparamNames[],StringparamTypes[],StringreturnName,StringreturnType){ this.serviceName=service.getName(); this.service=service; this.name=name; this.paramNames=paramNames; this.paramTypes=paramTypes; this.paramValues=newObject[this.paramNames.length]; this.returnName=returnName; this.returnType=returnType; this.returnValue=null;<!--SIPO<DPn="53">--><dpn="d53"/>}publicOperation(Operationoperation,intx,inty){ this.service=operation.service; this.serviceName=operation.serviceName; this.name=operation.name; this.paramNames=operation.paramNames; this.paramTypes=operation.paramTypes; this.paramValues=newObject[this.paramNames.length]; this.returnName=operation.returnName; this.returnType=operation.returnType; this.returnValue=null; this.x=x; this.y=y(tǒng); this.width=operation.width; this.height=operation.height;}publicStringtoString(){ StringBuffersbuf=newStringBuffer(); sbuf.append(returnType+″″+name+″(″); for(inti=0;i<paramNames.length;i++){ sbuf.append(paramTypes[i]+″″+paramNames[i]); if(i!=paramNames.length-1) sbuf.append(″,″); } sbuf.append(″)″); returnsbuf.toString();<!--SIPO<DPn="54">--><dpn="d54"/> } //---------Transferable-------------- publicbooleanisDataFlavorSupported(DataFlavordf){ returndf.equals(OPERATION_FLAVOR); } /**實(shí)現(xiàn)Transferable接口*/ publicObjectgetTransferData(DataFlavordf)throwsUnsupportedFlavorException,IOException{ if(df.equals(OPERATIONFLAVOR)){ returnthis; }else{ thrownewUnsupportedFlavorException(df); } } /**實(shí)現(xiàn)Transferable接口*/ publicDataFlavor[]getTransferDataFlavors(){ returnflavors; } /*publicvoidsetLoc(intx,inty){ this.x=x; this.y=y(tǒng); System.out.println(name+″setLoc@″+this.x+″,″+this.y); } */<!--SIPO<DPn="55">--><dpn="d55"/> publicvoiddraw(Graphicsg){ intfontH=g.getFontMetrics().getHeight(); recH=fontH+marginTop*2; //System.out.println(″drawatl+this.x+s,″+this.y+″″+name); //發(fā)現(xiàn)框的寬度 Stringtitle1=serviceName; Stringtitle2=this.returnType+″″+this.name; width=Math.max(g.getFontMetrics().stringWidth(title1),g.getFontMetrics().stringWidth(title2)); for(inti=0;i<this.paramNames.length;i++){ Stringparam=(String)this.paramTypes[i]+″″+(String)this.paramNames[i]+″*″; width=Math.max(width,g.getFontMetrics().stringWidth(param)); } width=width+marginLeft*2+connectorW*2; //繪制標(biāo)題 Rectangle2DtitleBar=newRectangle2D.Double(x,y,width+1,recH);//g.fill3DRect(x,y,width,recH,true); Graphics2Dg2=(Graphics2D)g; if(!running){ g2.setPaint(newGradientPaint(x,y,Color.darkGray,x+width+l,y+recH,Color.lightGray)); }else{ g2.setPaint(newGradientPaint(x,y,newColor(80,125,80),x+width+l,y+recH,newColor(80,255,80)));<!--SIPO<DPn="56">--><dpn="d56"/> } g2.fill(titleBar); g.setColor(Color.white); FontoldFont=g.getFont(); g.setFont(newFont(oldFont.getName(),F(xiàn)ont.BOLD,oldFont.getSize())); g.drawString(title1,x+marginLeft,y+marginTop+fontH); g.setColor(Color.black); g.setFont(oldFont); drawConnector(x,y+recH,width,recH,″out″,g); g.draw3DRect(x,y+recH,width,recH,true); g.drawString(title2,x+marginLeft,y+marginTop+fontH+recH); for(inti=0;i<this.paramNames.length;i++){ intcurY=y(tǒng)+(i+2)*recH; //if(inLink?。絥ull&&inLinkEil?。絥ull‖paramValues[i]!=null) drawConnector(x,curY,width,recH,″in″,g); g.draw3DRect(x,curY,width,recH,true); if(this.paramValues[i]?。絥ull) g.drawString((String)this.paramTypes[i]+″″+(String)this.paramNames[i]+″*″,x+marginLeft,curY+marginTop+fontH); else g.drawString((String)this.paramTypes[i]+″″+(String)this.paramNames[i],x+marginLeft,curY+marginTop+fontH); } height=recH*(this.paramNames.length+2);<!--SIPO<DPn="57">--><dpn="d57"/> } /*privatevoiddrawConnector(intpx,intpy,intrecW,intrecH,Stringtype,Graphicsg){ if(type.equals(″in″)){ g.fill3DRect(px-connectorW,py+recH/2-connectorH/2,connectorW,connectorH,true); }else{ g.fill3DRect(px+recW,py+recH/2-connectorH/2,connectorW,connectorH,true); } }*/privatevoiddrawConnector(intpx,intpy,intrecW,intrecH,Stringtype,Graphicsg){if(type.equals(″in″)){ intxPoints[]={px,px+connectorW,px}; intyPoints[]={py+recH/2-connectorH/2,py+recH/2,py+recH/2+connectorH/2}; g.fillPolygon(xPoints,yPoints,3); }else{ intxPoints[]={px+recW,px+recW+connectorW,px+recW}; intyPoints[]={py+recH/2-connectorH/2,py+recH/2,py+recH/2+connectorH/2}; g.fillPolygon(xPoints,yPoints,3); }<!--SIPO<DPn="58">--><dpn="d58"/>}privateStringgetDisplayName(){ StringBuffersbuf=newStringBuffer(); sbuf.append(returnType++name+″(″; for(inti=0;i<paramNames.length;i++){ sbuf.append(paramTypes[i]); if(i!=paramNames.length-1) sbuf.append(″,″); } sbuf.append(″)″); returnsbuf.toString();}/*publicLinkgetOutLink(){returnthis.outLink;}publicintgetX(){ returnthis.x;}publicintgetY(){ returnthis.y;}*//*//---------可串行化的--------------<!--SIPO<DPn="59">--><dpn="d59"/>privatevoidwriteObject(java.io.ObjectOutputStreamout)throwsIOException{ out.defaultWriteObject();}privatevoidreadObject(java.io.ObjectInputStreamin) throwsIOException,ClassNotFoundException{ in.defaultReadObject();}*/publicOperationselect(intposX,intposY){ if(posX>=x&&posX<=x+width+connectorW&&posY>=y(tǒng)&&posY<=y(tǒng)+height){ //System.out.println(″Operationselect″+this.name); returnthis; } else returnnull; } publicintselectInput(intposY){ if(posY>y+2*recH){ //System.out.println(″selectedindex=″+(posY-(y+2*recH))/recH); return(posY-(y+2*recH))/recH; } else return-1;<!--SIPO<DPn="60">--><dpn="d60"/> } publicbooleanisDragingTitle(intposX,intposY){ return(posY>=y(tǒng)&&posY<(y+recH)); } publicbooleanisDragingOutput(intposX,intposY){ return(posY>=(y+recH)&&posY<(y+2*recH)); } publicvoidsetParamValue(Stringinput,intindex){ this.paramValues[index]=input; } publicvoiddelParamValue(intindex){ this.paramValues[index]=null; } publicvoidsetParamValue(Objectinput,intindex){ intpos=paramTypes[index].indexOf(″″); Stringtype=paramTypes[index].substring(pos+1); if(type.equals(″string″)) this.paramValues[index]=(String)input; elseif(type.equals(″int″)) this.paramValues[index]=newInteger((String)input); elseif(type.equals(″float″)) this.paramValues[index]=newFloat((String)input);<!--SIPO<DPn="61">--><dpn="d61"/> elseif(type.equals(″double″)) this.paramValues[index]=newjava.lang.Double((String)input); else this.paramValues[index]=input; } publicvoidsetInLink(Linklink,intindex){ if(this.inLink==null) this.inLink=newLink[this.paramNames.length]; inLink[index]=link; } publicPointgetOutPoint(){ returnnewPoint(x+width+connectorW,y+recH+recH/2); } publicPointgetInPoint(intindex){ //System.out.println(″getInPointindex=″+index); returnnewPoint(x-connectorW,y+(index+2)*recH+recH/2); } publicStringgetReturuType(){ returnthis.returnType; } publicStringgetParamName(intindex){ returnthis.paramNames[index];<!--SIPO<DPn="62">--><dpn="d62"/>}publicStringgetParamType(intindex){ returnthis.paramTypes[index];}publicObjectgetParamValue(intindex){ returnthis.paramValues[index];}publicLinkgetInLink(intindex){ return(inLink==null?nullinLink[index]);}publicLink[]getInLink(){ returnthis.inLink;}publicObjectexecute(){ URLurl=null; try{ url=newURL(service.getUrl()); }catch(Exceptione){ } StringencodingStyleURI=Constants.NS_URI_SOAP_ENC; //構(gòu)建調(diào)用 Callcall=newCall(); call.setTargetObjectURI(service.getUrnt));<!--SIPO<DPn="63">--><dpn="d63"/> call.setMethodName(this.name); call.setEncodingStyleURI(encodingStyleURI); Vectorparams=newVector(paramNames.length); for(inti=0;i<paramNames.length;i++){ params.addElement(newParameter(paramNames[i],getJavaType(paramTypes[i]),paramValues[i],null)); } call.setParams(params); //進(jìn)行調(diào)用注意actionURI為空,因?yàn)閄ML-SOAPrpcrouter //不需要它。這在未來可能改變。 Responseresp=null; try{ resp=call.invoke(/*routerURL*/url,/*actionURI*/″″); }catch(org.apache.soap.SOAPExceptione){ returne.getMessage(); } //檢查響應(yīng)?! f(resp.generatedFault()){ Faultfault=resp.getFault(); System.out.println(″Ouch,thecallfailed″); System.out.println(″FaultCode=″+fault.getFaultCode()); System.out.println(″FaultString=″+fault.getFaultString()); returnfault.getFaultString(); }else{ Parameterresult=resp.getReturnValue(); //Stringvalue=(String)result.getValue(); //returnvalue;<!--SIPO<DPn="64">--><dpn="d64"/> returnresult.getValue(); }}staticClassgetJavaType(StringxmlType){ ClassaClass=null; intpos=xmlType.indexOf(″″); Stringtype=xmlType.substring(pos+1); try{ if(type.equals(″string″)) aclass=Class.forName(″java.lang.String″); elseif(type.equals(″int″)) aClass=Class.forName(″java.lang.Integerl′); elseif(type.equals(″float″)) aClass=Class.forName(″java.lang.Float″); elseif(type.equals(″double″)) aClass=Class.forName(″java.lang.Double″); elseaClass=Class.forName(″java.lang.Object″); }catch(Exceptione){} //System.out.println(″javatype=″+aClass); returnaClass;}booleanisSetable(intindex){ intpos=paramTypes[index].indexOf(″″); Stringtype=paramTypes[index].substring(pos+1); return(type.equals(″string″)‖ type.equals(″int″)‖<!--SIPO<DPn="65">--><dpn="d65"/>type.equals(″float″)‖ type.equals(″double″)); } booleanisParamValueAllSet(){ for(inti=0;i<paramValues.length;i++){ if(paramValues[i]==null){ returnfalse; } } returntrue; } booleanisParamOrLinkSet(){ for(inti=0;i<paramValues.length;i++){ if(paramValues[i]==null&&this.inLink[i]==null){ System.out.println(name+″isParamOrLinkSet()=false″); returnfalse; } returntrue; }}//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjavax.swing.JOptionPane;<!--SIPO<DPn="66">--><dpn="d66"/>importjavax.swing.JDialog;importjavax.swing.JTextField;importjava.beans.*;//屬性改變代碼importjava.awt.*;importjava.awt.event.*;/***該類提供了用于為Web服務(wù)方法調(diào)用設(shè)置參數(shù)的對(duì)話框。*/publicclassParamInputDialogextendsJDialog{ privateStringtypedText=null; privateJOptionPaneoptionPane; /** *構(gòu)造函數(shù) */ publicParamInputDialog(){ } publicStringgetValidatedText(){ returntypedText; } publicParamInputDialog(Stringname){ super(); setTitle(″Input″); this.setModal(true);<!--SIPO<DPn="67">--><dpn="d67"/> finalStringmsgString=″Setvaluefor″+name; finalJTextFieldtextField=newJTextField(50); Object[]array={msgString,textField}; finalStringbtnString1=″Enter″; finalStringbtnString2=″Cancel″; Object[]options={btnString1,btnString2}; optionPane=newJOptionPane(array,JOptionPane.QUESTION_MESSAGE,JOptionPane.YESNOOPTION,null,options,options); setContentPane(optionPane); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener(newWindowAdapter(){ publicvoidwindowClosing(WindowEventwe){ /* *不是直接關(guān)閉窗口,而是改變JOptionPane *的值屬性。 */ optionPane.setValue(newInteger(JOptionPane.CLOSED_OPTION)); } }); textField.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ optionPane.setValue(btnString1); } }); optionPane.addPropertyChangeListener(newPropertyChangeListener(){<!--SIPO<DPn="68">--><dpn="d68"/> publicvoidpropertyChange(PropertyChangeEvente){ Stringprop=e.getPropertyName(); if(isVisible()&&(e.getSource()==optionPane)&&(prop.equals(JOptionPane.VALUE_PROPERTY)‖prop.equals(JOptionPane.INPUT_VALUE_PROPERTE))){ Objectvalue=optionPane.getValue(); if(value==JOptionPane.UNINITIALIZED_VALUE){ //忽略重置 return; } //重置JOptionPane的值。如果不這樣,則當(dāng)用戶 //下次按下同一個(gè)鍵時(shí),將不會(huì)觸發(fā)屬性改變事件?! ptionPane.setValue (JOptionPane.UNINITIALIZED_VALUE); if(value.equals(btnStringl)){ typedText=textField.getText(); }else{//用戶關(guān)閉對(duì)話框或點(diǎn)擊取消?! ypedText=null; setVisible(false); } } } }); }}<!--SIPO<DPn="69">--><dpn="d69"/>//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.util.*;importjava.io.*;importjava.net.URL;importorg.apache.xerces.parsers.DOMParser;importorg.w3c.dom.*;importcom.ibm.wsdl.*;/***代表Web服務(wù)對(duì)象的核心類。*/publicclassServiceextendsObjectimplementsSerializable{ Stringname; Stringurn; Stringurl; VectoroperationVec; /** *構(gòu)造函數(shù) */ publicService(){ } publicService(Filefile)throwsException{ com.ibm.wsdl.WSDLDocumentwsdldom=null;<!--SIPO<DPn="70">--><dpn="d70"/>wsdldom=newcom.ibm.wsdl.WSDLDocument(file.getAbsolutePath());initService(wsdldom);}publicService(Stringurl)throwsException{com.ibm.wsdl.WSDLDocumentwsdldom=null;System.out.println(″constructingServicefrom″+url);wsdldom=newcom.ibm.wsdl.WSDLDocument(newURL(url));initService(wsdldom);}voidinitService(com.ibm.wsdl.WSDLDocumentwsdldom){WSDLMessageElementmsgs[]=wsdldom.getMessageElements();com.ibm.wsdl.WSDL.ServiceElementserviceElems[]=wsdldom.getServiceElements();name=serviceElems[OlgetDomElement().getAttributes().item(0).getNodeValue();//System.out.println(name);WSDLPortElement[]servPorts=serviceElems.getPortElements();NodeListnodes=servPorts.getDomElement().getChildNodes();for(inti=0;i<nodes.getLength();i++){Stringlocalname=nodes.item(i).getLocalName();if(localname?。絥ull&&localname.equals(″address″)){url=nodes.item(i).getAttributes().getNamedItem<!--SIPO<DPn="71">--><dpn="d71"/>(″location″).getNodeValue();break;}}urn=initUrn(wsdldom);//System.out.println(″url=″+url+″urn=″+urn);WSDLPortTypeElementports[]=wsdldom.getPortTypeElements();WSDLOperationElementoperations[]=ports.getOperationElements();initOperation(msgs,operations);}StringinitUrn(WSDLDocumentwsdldom)throwsjava.lang.NullPointerException{Elementbinding=wsdldom.getBindingElements().getDomElement();Nodeoper=binding.getElementsByTagName(″operation″).item(0);NodeListchildren=oper.getChildNodes();Nodenode=null;for(inti=0;i<children.getLength();i++){node=children.item(i);if(node.getNodeName().equals(″input″)){break;}}//System.out.println(″Inputnodename=″+node.getLocalName<!--SIPO<DPn="72">--><dpn="d72"/>());children=node.getChildNodes();//System.out.println(″length=″+node.getChildNodes().getLength());for(inti=0;i<children.getLength();i++){node=children.item(i);//System.out.println(node.getNodeNamei));if(node.getNodeName().indexOf(″body″)>=0){break;}}//System.out.println(″soapbodyname=″+node.getLocalName());urn=node.getAttributes().getNamedItem(″namespace″).getNodeValue();returnurn;}voidinitOperation(WSDLMessageElement[]msgs,WSDLOperationElement[]operations){HashtablemsgTable=newHashtable(10);for(inti=0;i<msgs.length;i++){msgTable.put(msgs[i].getName(),msgs[i].getPartElements());//System.out.println(msgs[i].getName());}operationVec=newVector(operations.length);for(inti=0;i<o(jì)perations.length;i++){<!--SIPO<DPn="73">--><dpn="d73"/> Stringname=operations[i].getName(); StringinMsg=operations[i].getInputElement().getMessage(); WSDLPartElement[]inParts=(WSDLPartElement[])msgTable.get(inMsg); //System.out.println(″inMsg=″+inMsg); StringpartNames[]=newString[inParts.length]; StringpartTypes[]=newString[inParts.length]; for(intj=0;j<inParts.length;j++){ partNames[j]=inParts[j].getName(); partTypes[j]=inParts[j].getType(); //System.out.println(inParts[j].getType()+″″+inParts[j].getName()); } StringoutMsg=operations[i].getOutputElement().getMessage(); //System.out.println(″outMsg=″+outMsg); WSDLPartElement[]outParts=(WSDLPartElement[])msgTable.get(outMsg); StringreturnName=outParts.getName(); StringreturnType=outParts.getType(); //System.out.println(″return=″+returnName+″″+returnType); Operationoper=newOperation(this,name,partNames,partTypes,returnName,returnType); operationVec.add(oper); } }<!--SIPO<DPn="74">--><dpn="d74"/>publicVectorgetOperationVec(){ returnoperationVec;}/*publicService(Filefile){ parse(file);}voidparse(Filefile){ Documentdoc=null; VectorparamNames=null; VectorparamTypes=null; StringreturnName=null; StringreturnType=null; try { DOMParserparser=newDOMParser(); parser.parse(file.getAbsolutePath()); doc=parser.getDocument(); } catch(Exceptione) { System.err.println(″Sorry,anerroroccurred″+e); return; } //已經(jīng)分析了文檔,現(xiàn)在打印它。 //獲得Service名稱<!--SIPO<DPn="75">--><dpn="d75"/> NodeListnodes=doc.getElementsByTagName(″service″); name=nodes.item(0).getAttributes().getNamedItem(″name″).getNodeValue(); //獲得操作 nodes=doc.getElementsByTagName(″operation″); operations=newVector(); //遍歷所有操作 for(inti=0;i<nodes.getLength();i++){ Nodenode=nodes.item(i); //獲得操作名稱 StringoperationName=node.getAttributes().getNamedItem(″name″).getNodeValue(); NodeListmsgNodes=node.getChildNodes(); //獲得輸入、輸出消息 Stringinputmsg,outputmsg; if(msgNodes.item(0).getNodeName().equals(″input″)){ inputmsg=msgNodes.item(0).getAttributes().getNamedItem(″name″).getNodeValue(); outputmsg=msgNodes.item(1).getAttributes().getNamedItem(″name″).getNodeValue(); } else{ outputmsg=msgNodes.item(0).getAttributes().getNamedItem(″name″).getNodeValue(); inputmsg=msgNodes.item(1).getAttributes().getNamedItem(″name″).getNodeValue(); } NodeListmsgnodes=doc.getElementsByTagName<!--SIPO<DPn="76">--><dpn="d76"/>(″message″); intcount=0; for(intj=0;j<msgnodes.getLength();j++){ if(msgnodes.item(j).getAttributes().item(0).getNodeValue().equals(inputmsg)){ Nodemsgnode=msgnodes.item(j); NodeListchildren=msgnode.getChildNodes(); paramNames=newVector(); paramTypes=newVector(); for(intk=0;k<children.getLength();k++){ NamedNodeMapattribs=children.item(k).getAttributes(); paramNames.addElement(attribs.getNamedItem(″name″).getNodeValue());paramTypes.addElement(attribs.getNamedItem(″type″).getNodeValue()); } count++; } if(msgnodes.item(j).getAttributes().item(0).getNodeValue().equals(outputmsg)){ Nodemsgnode=msgnodes.item(j).getFirstChild(); returnName=msgnode.getAttributes().getNamedItem(″name″).getNodeValue(); returnType=msgnode.getAttributes().getNamedItem(″type″).getNodeValue(); count++; }<!--SIPO<DPn="77">--><dpn="d77"/> if(count==2)break; } operations.addElement(newOperation(operationName,paramNames,paramTypes,returnName,returnType)); } } */ StringgetName(){ returnname; } publicStringtoString(){ returnname; } StringgetUrl(){ returnurl; } StringgetUrn(){ returnurn; } //Copyright(c)2001IBMpackage com.ibm.webahead.flow;<!--SIPO<DPn="78">--><dpn="d78"/>importjavax.swing.*;importjavax.swing.event.*;importjavax.swing.plaf.metal.*;importjavax.swing.tree.*;importjava.awt.*;importjava.awt.datatransfer.*;importjava.awt.dnd.*;importjava.awt.dnd.peer.*;importjava.awt.event.*;importjava.io.*;importjava.util.*;/***該類代表包含一個(gè)工作流的內(nèi)部框架。*/publicclassWorkFlowFrameextendsJInternalFrame//實(shí)現(xiàn)DropTargetListener{WorkFrameparent; WorkFlowworkflow; /** *構(gòu)造函數(shù) */ publicWorkFlowFrame(Stringtitle,WorkFrameparent,WorkFlowworkflow){ super(title,true,true,true,true); this.parent=parent;<!--SIPO<DPn="79">--><dpn="d79"/> this.workflow=workflow; this.setContentPane(newFlowPane(parent,this,workflow)); } publicWorkFlowgetWorkflow(){ returnthis.workflow; } publicvoidsetWorkflow(WorkFlowworkflow){ this.workflow=workflow; ((FlowPane)this.getContentPane()).setWorkflow(workflow); }}//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.util.*;importjavax.swing.*;importjavax.swing.tree.*;importjava.io.*;importjava.io.*;/***該類代表包括一工作流集合的工作空間。*/publicclassWorkSpaceextendsObjectimplementsSerializable{ //Stringfolder;<!--SIPO<DPn="80">--><dpn="d80"/>DefaultMutableTreeNoderoot; VectorflowVec; VectorserviceVec; /** *構(gòu)造函數(shù) */ publicWorkSpace(){ } publicWorkSpace(Filedir){ serviceVec=newVector(); flowVec=newVector(); root=newDefaultMutableTreeNode(″Untitled.wsp″); Filefiles[]=dir.listFiles(); for(inti=0;i<files.length;i++){ Filefile=files[i]; Serviceservice=null; try{ service=newService(files[i]); }catch(Exceptione){ System.out.println(″e(cuò)rrorinconstructing″+files[i].getName()); e.printStackTrace(); break; } serviceVec.addElement(service);<!--SIPO<DPn="81">--><dpn="d81"/> DefaultMutableTreeNodenode=newDefaultMutableTreeNode(service,true); VectoroperVec=service.getOperationVec(); for(intj=0;j<o(jì)perVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } root.add(node); } } publicWorkSpace(File[]files){ serviceVec=newVector(); flowVec=newVector(); root=newDefaultMutableTreeNode(″Untitled.wsp″); for(inti=0;i<files.length;i++){ Filefile=files[i]; Serviceservice=null; try{ service=newService(files[i]); }catch(Exceptione){ System.out.println(″e(cuò)rrorinconstructing″+files[i].getName()); e.printStackTrace(); break; } serviceVec.addElement(service);<!--SIPO<DPn="82">--><dpn="d82"/> DefaultMutableTreeNodenode=newDefaultMutableTreeNode(service,true); VectoroperVec=service.getOperationVec(); for(intj=0;j<o(jì)perVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } root.add(node); } } publicWorkSpace(Vectorurls){ serviceVec=newVector(); flowVec=newVector(); root=newDefaultMutableTreeNode(″Untitled.wsp″); for(inti=0;i<urls.size();i++){ Stringurl=(String)urls.elementAt(i); Serviceservice=null; try{ service=newService(url); }catch(Exceptione){ System.out.println(″e(cuò)rrorinconstructing″+url); e.printStackTrace(); break; } serviceVec.addElement(service); DefaultMutableTreeNodenode=new<!--SIPO<DPn="83">--><dpn="d83"/>DefaultMutableTreeNode(service,true); VectoroperVec=service.getOperationVec(); for(intj=0;j<o(jì)perVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } root.add(node); } } voidaddWSDL(DefaultTreeModeltreemodel,F(xiàn)ile[]files){ for(inti=0;i<files.length;i++){ Filefile=files[i]; Serviceservice=null; try{ service=newService(files[i]); }catch(Exceptione){ System.out.println(″e(cuò)rrorinconstructing″+files[i].getName()); e.printStackTrace(); break; } if(isDuplicatedService(service)) continue; serviceVec.addElement(service);<!--SIPO<DPn="84">--><dpn="d84"/> DefaultMutableTreeNodenode=newDefaultMutableTreeNode(service,true); VectoroperVec=service.getOperationVec(); for(intj=0;j<o(jì)perVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } DefaultMutableTreeNodeparentNode=(DefaultMutableTreeNode)treemodel.getRoot(); treemodel.insertNodeInto(node,parentNode,parentNode.getChildCount()); } } publicvoidaddWSDL(DefaultTreeModeltreemodel,Vectorurls){ for(inti=0;i<urls.size();i++){ Stringurl=(String)urls.elementAt(i); Serviceservice=null; try{ service=newService(url); }catch(Exceptione){ System.out.println(″e(cuò)rrorinconstructing″+url); e.printStackTrace(); break; }<!--SIPO<DPn="85">--><dpn="d85"/> if(isDuplicatedService(service)) continue; serviceVec.addElement(service); DefaultMutableTreeNodenode=newDefaultMutableTreeNode(service,true); VectoroperVec=service.getOperationVec(); for(intj=0;j<o(jì)perVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } treemodel.insertNodeInto(node,root,root.getChildCount()); } } DefaultMutableTreeNodegetRoot(){ returnroot; } voiddeleteService(DefaultTreeModeltreemodel,DragTreetree){ if(treemodel?。絥ull&&tree?。絥ull&&tree.getSelectedNode()!=null){ DefaultMutableTreeNodeselectedNode=(DefaultMutableTreeNode)(tree.getLastSelectedPathComponent()); if(tree.getSelectedNode().isLeaf()){ selectedNode=(DefaultMutableTreeNode)<!--SIPO<DPn="86">--><dpn="d86"/>selectedNode.getParent(); } Serviceservice=(Service)selectedNode.getUserObject(); serviceVec.remove(service); treemodel.removeNodeFromParent(selectedNode); } } booleanisDuplicatedService(Serviceservice){ for(inti=0;i<serviceVec.size();i++){ if(((Service)serviceVec.elementAt(i)).getName().equals(service.getName())) returntrue; } returnfalse; }}權(quán)利要求1.一種用于在Web服務(wù)環(huán)境中創(chuàng)建計(jì)算機(jī)程序的方法,該方法包括以下步驟將第一Web服務(wù)程序的第一表示移動(dòng)到一GUI顯示分區(qū)內(nèi);將第二程序的第二表示移動(dòng)到該GUI顯示分區(qū)內(nèi);以及使用GUI功能將該第一表示與第二表示互連,其中該第一Web服務(wù)程序與該第二程序可編程地通信以執(zhí)行希望的操作。2.根據(jù)權(quán)利要求1的方法,還包括以下步驟使用GUI功能選擇第一表示或第二表示中的任何一個(gè);以及使用GUI功能設(shè)定所選擇的表示的參數(shù)。3.根據(jù)權(quán)利要求1的方法,其中,所述GUI功能包括鼠標(biāo)、鼠標(biāo)按鈕、鍵盤、觸摸屏、觸控板、語音識(shí)別技術(shù)、光標(biāo)定位或光筆中的任何一個(gè)。4.根據(jù)權(quán)利要求1的方法,其中,所述第一表示或第二表示中的任何一個(gè)是顯示的圖標(biāo)。5.根據(jù)權(quán)利要求1的方法,其中,移動(dòng)所述表示的功能是拖放。6.根據(jù)權(quán)利要求2的方法,其中,所述設(shè)定參數(shù)的步驟還包括以下步驟使用GUI功能啟動(dòng)參數(shù)選項(xiàng)的顯示;根據(jù)預(yù)定的計(jì)劃在該參數(shù)選項(xiàng)的顯示上進(jìn)行操作;以及退出該參數(shù)選項(xiàng)的顯示。7.根據(jù)權(quán)利要求1的方法,還包括以下步驟啟動(dòng)對(duì)所述互連的表示的檢測;以及突出顯示所述第一表示以指示功能狀態(tài)。8.根據(jù)權(quán)利要求7的方法,其中,所述突出顯示指示空閑、工作、錯(cuò)誤或警告中的任何一個(gè)。9.根據(jù)權(quán)利要求7的方法,其中,所述突出顯示是通過顏色、亮度、文本消息、形狀改變或音頻消息中的任何一個(gè)來實(shí)現(xiàn)的。10.根據(jù)權(quán)利要求1的方法,還包括以下步驟將所述第一和第二表示以及互連保存為一封裝體表示。11.根據(jù)權(quán)利要求10的方法,其中,所述封裝體表示被放置在用戶的菜單上作為程序的第三表示。12.根據(jù)權(quán)利要求1的方法,還包括以下步驟創(chuàng)建所述第一Web服務(wù)的第一表示,以及將所創(chuàng)建的第一表示放置在用戶的菜單上。13.根據(jù)權(quán)利要求12的方法,其中,從所述用戶菜單、網(wǎng)頁或系統(tǒng)創(chuàng)建的下拉菜單中的任何一個(gè)移動(dòng)所述第一表示。14.根據(jù)權(quán)利要求1的方法,其中,從由所述Web服務(wù)提供的WSDL創(chuàng)建所述第一表示。15.根據(jù)權(quán)利要求1的方法,其中,所述互連步驟包括UDDI集成。16.根據(jù)權(quán)利要求1的方法,其中,所述希望的操作包括創(chuàng)建音頻文件、視頻文件、文本可查看文件、外部程序執(zhí)行、圖形用戶界面改變或圖形用戶界面對(duì)話框中的任何一個(gè)。17.根據(jù)權(quán)利要求1的方法,其中,所述第二程序是Web服務(wù)程序。18.一種用于在Web服務(wù)環(huán)境中創(chuàng)建計(jì)算機(jī)程序的計(jì)算機(jī)程序產(chǎn)品,該計(jì)算機(jī)程序產(chǎn)品包括具有計(jì)算機(jī)可讀程序代碼的計(jì)算機(jī)可讀介質(zhì),所述程序代碼包括用于將第一Web服務(wù)程序的第一表示移動(dòng)到一GUI顯示分區(qū)內(nèi)的計(jì)算機(jī)可讀程序代碼;用于將第二程序的第二表示移動(dòng)到該GUI顯示分區(qū)內(nèi)的計(jì)算機(jī)可讀程序代碼;以及用于使用GUI功能將該第一表示與第二表示互連的計(jì)算機(jī)可用于使用GUI功能將該第一表示與第二表示互連的計(jì)算機(jī)可讀程序代碼,其中該第一Web服務(wù)程序與該第二程序可編程地通信以執(zhí)行希望的操作。19.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,還包括以下步驟用于使用GUI功能選擇所述第一表示或第二表示中的任何一個(gè)的計(jì)算機(jī)可讀程序代碼;以及用于使用GUI功能設(shè)定所選擇的表示的參數(shù)的計(jì)算機(jī)可讀程序代碼。20.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,所述GUI功能包括鼠標(biāo)、鼠標(biāo)按鈕、鍵盤、觸摸屏、觸控板、語音識(shí)別技術(shù)、光標(biāo)定位或光筆中的任何一個(gè)。21.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,所述第一表示或第二表示中的任何一個(gè)是顯示的圖標(biāo)。22.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,移動(dòng)所述表示的計(jì)算機(jī)可讀程序代碼包括拖放。23.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,所述設(shè)定參數(shù)的計(jì)算機(jī)可讀程序代碼還包括用于使用GUI功能啟動(dòng)參數(shù)選項(xiàng)的顯示的計(jì)算機(jī)可讀程序代碼;用于根據(jù)預(yù)定的計(jì)劃在該參數(shù)選項(xiàng)的顯示上進(jìn)行操作的計(jì)算機(jī)可讀程序代碼;以及用于退出該參數(shù)選項(xiàng)的顯示的計(jì)算機(jī)可讀程序代碼。24.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,還包括用于啟動(dòng)對(duì)所述互連的表示的檢測的計(jì)算機(jī)可讀程序代碼;以及用于突出顯示所述第一表示以指示功能狀態(tài)的計(jì)算機(jī)可讀程序代碼。25.根據(jù)權(quán)利要求24的計(jì)算機(jī)程序產(chǎn)品,其中,所述突出顯示指示空閑、工作、錯(cuò)誤或警告中的任何一個(gè)。26.根據(jù)權(quán)利要求24的計(jì)算機(jī)程序產(chǎn)品,其中,所述突出顯示是通過顏色、亮度、文本消息、形狀改變或音頻消息中的任何一個(gè)來實(shí)現(xiàn)的。27.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,還包括用于將所述第一和第二表示以及互連保存為一封裝體表示的計(jì)算機(jī)可讀程序代碼。28.根據(jù)權(quán)利要求27的計(jì)算機(jī)程序產(chǎn)品,其中,所述封裝體表示被放置在用戶的菜單上作為程序的第三表示。29.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,還包括用于創(chuàng)建所述第一Web服務(wù)的第一表示的計(jì)算機(jī)可讀程序代碼,以及用于將所創(chuàng)建的第一表示放置在用戶的菜單上的計(jì)算機(jī)可讀程序代碼。30.根據(jù)權(quán)利要求29的計(jì)算機(jī)程序產(chǎn)品,其中,從所述用戶菜單、網(wǎng)頁或系統(tǒng)創(chuàng)建的下拉菜單中的任何一個(gè)移動(dòng)所述第一表示。31.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,從由所述Web服務(wù)提供的WSDL創(chuàng)建所述第一表示。32.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,所述用于互連的計(jì)算機(jī)可讀程序代碼包括用于UDDI集成的計(jì)算機(jī)可讀程序代碼。33.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,所述希望的操作包括創(chuàng)建音頻文件、視頻文件、文本可查看文檔、外部程序執(zhí)行、圖形用戶界面改變或圖形用戶界面對(duì)話框中的任何一個(gè)。34.根據(jù)權(quán)利要求18的計(jì)算機(jī)程序產(chǎn)品,其中,所述第二程序是Web服務(wù)程序。35.一種用于在Web服務(wù)環(huán)境中創(chuàng)建計(jì)算機(jī)程序的系統(tǒng),該系統(tǒng)包括以下裝置將第一Web服務(wù)程序的第一表示移動(dòng)到一GUI顯示分區(qū)內(nèi)的移動(dòng)器;將第二Web服務(wù)程序的第二表示移動(dòng)到該GUI顯示分區(qū)內(nèi)的移動(dòng)器;以及使用GUI功能將該第一表示與第二表示互連的互連器,其中該第一Web服務(wù)程序與該第二程序可編程地通信以執(zhí)行希望的操作。36.根據(jù)權(quán)利要求35的系統(tǒng),還包括使用GUI功能選擇第一表示或第二表示中的任何一個(gè)的選擇器;以及使用GUI功能設(shè)定所選擇的表示的參數(shù)的參數(shù)設(shè)定器。37.根據(jù)權(quán)利要求35的系統(tǒng),其中,所述GUI功能包括鼠標(biāo)、鼠標(biāo)按鈕、鍵盤、觸摸屏、觸控板、語音識(shí)別技術(shù)、光標(biāo)定位或光筆中的任何一個(gè)。38.根據(jù)權(quán)利要求35的系統(tǒng),其中,所述第一表示或第二表示是顯示的圖標(biāo)。39.根據(jù)權(quán)利要求35的系統(tǒng),其中,移動(dòng)所述表示的功能是拖放。40.根據(jù)權(quán)利要求36的系統(tǒng),其中,所述參數(shù)設(shè)定器還包括使用GUI功能啟動(dòng)參數(shù)選項(xiàng)的顯示的顯示啟動(dòng)器;根據(jù)預(yù)定的計(jì)劃在該參數(shù)選項(xiàng)的顯示上進(jìn)行操作的操作器;以及退出該參數(shù)選項(xiàng)的顯示的退出器。41.根據(jù)權(quán)利要求35的系統(tǒng),還包括啟動(dòng)對(duì)所述互連的表示的檢測的啟動(dòng)器;以及突出顯示所述第一表示以指示功能狀態(tài)的修改器。42.根據(jù)權(quán)利要求41的系統(tǒng),其中,所述突出顯示指示空閑、工作、錯(cuò)誤或警告中的任何一個(gè)。43.根據(jù)權(quán)利要求41的系統(tǒng),其中,所述突出顯示是通過顏色、亮度、文本消息、形狀改變或音頻消息中的任何一個(gè)來實(shí)現(xiàn)的。44.根據(jù)權(quán)利要求35的系統(tǒng),還包括將所述第一和第二表示以及互連保存為一封裝體表示的表示保存器。45.根據(jù)權(quán)利要求44的系統(tǒng),其中,所述封裝體表示被放置在用戶的菜單上作為程序的第三表示。46.根據(jù)權(quán)利要求35的系統(tǒng),還包括創(chuàng)建第一Web服務(wù)的第一表示的創(chuàng)建器,以及將所創(chuàng)建的第一表示放置在用戶的菜單上的菜單放置器。47.根據(jù)權(quán)利要求45的系統(tǒng),其中,從用戶菜單、網(wǎng)頁或系統(tǒng)創(chuàng)建的下拉菜單中的任何一個(gè)移動(dòng)所述第一表示。48.根據(jù)權(quán)利要求35的系統(tǒng),其中,從由Web服務(wù)提供的WSDL創(chuàng)建所述第一表示。49.根據(jù)權(quán)利要求35的系統(tǒng),其中,所述互連器還包括UDDI集成。50.根據(jù)權(quán)利要求35的系統(tǒng),其中,所述希望的操作包括創(chuàng)建音頻文件、視頻文件、文本可查看文件、外部程序執(zhí)行、圖形用戶界面改變或圖形用戶界面對(duì)話框中的任何一個(gè)。51.根據(jù)權(quán)利要求35的系統(tǒng),其中,所述第二程序是Web服務(wù)程序。全文摘要本發(fā)明提供了一種用于從Web服務(wù)建立程序的圖形用戶界面(GUI)接口。該與Web服務(wù)的接口在用戶菜單中優(yōu)選地由圖標(biāo)和文本表示。用戶將代表Web服務(wù)的圖標(biāo)從菜單拖放到顯示區(qū)域,并將該圖標(biāo)與代表其他程序?qū)嶓w(優(yōu)選地為其他Web服務(wù))的其他圖標(biāo)互連。優(yōu)選地,在拖放之后在該顯示區(qū)域內(nèi)創(chuàng)建一更詳細(xì)的圖標(biāo)。將在該顯示區(qū)域內(nèi)完成的互連圖標(biāo)的集合保存為一個(gè)新的程序?qū)嶓w。本發(fā)明還包括在測試模式下使通過模型的信息流可視化。文檔編號(hào)G06F9/44GK1761943SQ200480007469公開日2006年4月19日申請日期2004年3月17日優(yōu)先權(quán)日2003年4月2日發(fā)明者B·古德曼,J·凱賓格,K·拉加德,R·羅杰斯,舒晨申請人:國際商業(yè)機(jī)器公司