专利名称::通过使用图形用户界面控件来组合Web服务的程序创建的制作方法
技术领域:
:本发明涉及在万维网上编程。本发明尤其涉及使用GUI控件来组合网络程序对象(Web服务)以创建新地程序对象。
背景技术:
:万维网(Web)是目前流行的计算机连网平台,每天有数百万的人将万维网用于多种应用,从个人电子邮件和研究目的的“网上冲浪”到很复杂的商业和科学使用。发展出Web是为了使因特网的使用简单和容易。其概念是在用户(客户端)个人计算机(PC)处提供浏览器程序,以解释来自使用HTML和图形文件的主机服务器的信息。因特网提供通信手段以使Web客户机和服务器互连。Web服务是可被服务器访问并且为客户群体实现功能的程序。在一个示例中,Web服务提供证券报价机信息。已知一Web服务可用的客户可访问该Web服务以实现一个操作,否则客户必须为此创建一个程序。由于Web服务可用,因此客户仅需知道如何与Web服务接口,并且客户可将Web服务的功能并入自己的本地应用。为了知道如何与Web服务接口,程序员需要理解接口语言。一种这样的语言是Web服务描述语言(WSDL)(根据存在于Web上www.w3.org/TR/wsdl处的W3C标准),其是一种基于XML的语言,用于描述与Web服务的接口。作为服务器的内容提供者运行的Web服务向客户程序提供WSDL文档。该WSDL文档定义了接口模式,从而客户可知道Web服务接口所需的格式、协议等。客户需要理解Web服务的功能(例如其提供证券报价,并且数据被加密)。每个Web服务还定义了自身的术语。Web服务接口语言使得程序员更容易编写代码以将Web服务的功能并入定制的程序,但是,需要编程知识(WSDL、XML、HTML等)来实现这一点。
发明内容本发明的目标是简化使用Web服务的程序创建。本发明提供了用户可用的Web服务(或可选地其他程序)的列表(菜单)。程序员使用一创建器程序,该程序为本发明将支持的每个Web服务创建图标支持。一菜单放置器功能将创建的图标放置在菜单内。还为非Web服务的定制程序创建图标。这种图标可用于提供例如音频、视频、机械接口。通过授权代理或从内容提供者获取图标,使图标对于用户可用。优选地,每个图标均由标题以及支持性描述文本来表示。该标题以及可选的描述文本在用户的客户计算机与相关联的通用图标图像一起显示。该图标包括对程序代码的访问、Web服务接口控件、以及可视特性。用户选择图标标题并(使用UBI移动器)将其拖入框架(画布)。然后,用户可在该框架内执行该图标以检测其功能。用户可将该图标与该框架内的其他对象互连(使用互连器GUI1506),以创建新的功能。当将图标拖到框架内时,优选地创建更详细的图标,该图标可见地显示了接口选择(如果适用的话),从而当用户互连该对象时,用户可通过选择(使用GUI选择器)合适的可视表示来选择(例如)英语或西班牙语语言转换。用户可使用参数设置器GUI来设定合适的参数以定制所选择的图标的功能。在一个实施例中,用户使用显示启动器GUI来显示图标的参数选项;然后,使用在参数显示上操作的操作器,用户设定合适的参数;最后,用户使用退出器GUI来退出参数显示。在一个实施例中,用户可检测定制的图标的功能。用户使用启动器GUI来启动该检测。执行该检测,并导致GUI修改器修改显示的视觉表示以便根据检测功能来指示该图标的功能状态。该显示可改变颜色、亮度、文本消息显示,可进行形状改变或实现声音表示。在一个实施例中,由表示保存器将互连的图标保存为封装体(capsule)表示。被保存的封装体表示进一步由封装体图标表示,从而可将其添加到用户的可用图标列表内。当用户满意框架内的互连图标的功能时,用户将该框架结构保存为命名的程序实体。将来,用户可将该命名的程序实体作为单个对象来执行。在一个实施例中,可给该命名的程序实体本身分配一个图标,从而在新框架的拖放创建中可使用该命名的程序实体。因此,本发明的一个目的是为Web服务提供具有可选的可视属性的拖放图标。本发明的另一个目的是提供一种用于互连拖放图标以创建新功能的机制。从下面结合附图对本发明的详细说明,本领域内的技术人员可清楚地了解本发明的这些以及其他目的,在该些附图中图1是用于执行程序应用的计算机系统的高层描述。图2是使用大量互连的计算机系统的计算机网络的高层描述。图3是使用本发明的GUI显示的示例性视图4放大了图3的一部分以描述一图标列表;图5放大了图3的一部分以描述从图4的列表中拖出的互连图标;图6示出启动和保存图标的流程;图7示出创建互连的一组图标的流程;图8示出执行互连的一组图标的流程;图9示出访问SOAP封装体的流程;图10示出封装体的WSDL生成的流程;图11示出SOAP桥的流程;图12示出IDS请求的流程;图13示出服务器流程的一个示例;图14示出一直线流;图15示出一单记录流,其中任务在不同的计算机上并行执行;图16示出一多记录流,其中任务在不同的计算机上并行执行;图17示出一并行流;以及图18示出具有开关操作器的流。具体实施例方式图1示出一可用于Web或因特网对等网络通信以及执行面向对象的程序例如本发明的那些程序的示例性计算机系统。该系统包括处理器106,该处理器用于执行从存储器105取得的程序指令。存储媒体107(磁的或光的)用于保存当前没有被处理器106操作的程序和数据。基计算机(basecomputer)可选地具有外围设备,该些外围设备连接在该基计算机上以提供用户接口。通常,外围设备包括显示器102、键盘104和网络连接108。可选地,鼠标103、打印机/扫描仪110也连接到该示例性计算机系统上。存储媒体107中保存的程序111被页入(pageinto)到存储器105内以便处理器进行处理。程序111包括操作系统和包括例如本发明的应用的应用。面向对象的程序是在运行期间生成程序对象的程序。这些对象被保存在存储器105中以便由处理器执行。图2示出多个通过本发明可使用的本地网络和因特网网络互连的不同设计的计算机系统。客户计算机201-205直接与用户交互,并提供了用于请求信息的装置。服务器206-207接收客户请求,并作为响应执行操作。该操作可以是仅检索信息(例如构成网页的HTML、GIF文件),提供到因特网网络的路径,或触发在服务器上运行的定制程序(CGI脚本)或在客户计算机上运行的JAVA小应用程序。还存在对等网络,其中一计算机可作为客户机和服务器运行,从而使得计算机可直接通信。术语表UDDI(通用描述、发现和集成)是Web服务和Web上的企业名称、产品以及位置的基于XML的注册库。WSFL(Web服务流语言)是由IBM设计的用于描述Web服务组合的基于XML的语言。其依赖于并补充其他规范例如SOAP、WSDL、XMLP和UDDI等。SOAP(简单对象访问协议)是用于交换信息的基于XML的协议。SOAP包括一包封(envelope),该包封定义了一个用于描述消息以及如何处理消息的框架、编码规则以及用于代表远程过程的约定。XMLP是一组控制XML消息的格式和处理以及应用交互的正式约定。IDS(智能决策服务器),也称DIS(分布式综合解决方案),见转让给IBM的美国专利6094655(Roger等人)“MethodofcreatingandusingNotesdecisioncapsules”。IDS执行所选择的身为串在一起的封装体元件的程序封装体。Web服务是通常可利用万维网从远程服务器得到的应用。Web服务优选地使用WSDL(描述Web服务的接口的基于XML的文档)对自身进行描述。提供目录(在概念上,其相当于电话号码簿),从而可用户可发现可用的服务,优选地为UDDI。还提供了用于在Web服务和其客户之间通信的工具,优选地为SOAP。本发明是在Web服务环境以及以下文献中说明的现有技术上发展而来的美国专利6094655“MethodofcreatingandusingNotesdecisioncapsules”(Roger等人);美国专利5710918“AmethodfordistributedtaskfulfillmentofWebbrowserrequests”;美国专利5701451“AMethodforfulfillingrequestsofawebBrowser”;美国专利5721908“ComputernetworkforWWWserverdataaccessoverInternet”;美国专利5752246“AserviceagentforfulfillingrequestsofaWebbrowser”;美国专利5745754“Asub-agentforfulfillingrequestsofaWebbrowserusinganintelligentagentandprovidingareport”;以及美国专利5974441“WWWclientserverinteractivesystemmethodwithJava”。所有这些专利都转让给了美国国际商业机器公司(IBM),并且被并入本文中作为参考文献。随着Web服务在因特网上的出现,使用这些服务建立新应用成为一种新的开发应用的方法。通常,Web服务由独立的组开发,而以有意义的方式将这些服务组合在一起并不容易实现。本发明允许非开发人员在一个“封装的”过程流(processflow)中创建、组合、包装并一起使用这些服务。本发明提供了一种用于组合和封装可能从未打算合作的Web服务的方法。本发明提供了一种定义Web服务之间的连接,并建立(Web)服务工作流的组合的方法。这些通过连接而组合的服务被成为封装体(在一过程流中连接在一起的Web服务序列)。在我们的方法中,一Web服务的输出被原样获得,并用作另一个Web服务(或一组并行的Web服务)的输入。或者,可选地,一Web服务的输出在被用作另一个Web服务的输入之前被转换和变换。变换器是本地服务的功能(成套工具的一部分),或者在另一实施例中,变换是由变换器Web服务实现的。这些Web服务的组合或封装的过程流(封装体)均可由不需要具有程序员的技能的用户(使用我们提供的工具)使用“可视流构造器”(用于Web服务的封装体)构建。在一个实施例中,该工具具有UDDI集成,从而用户可访问因特网上的任何Web服务,并将该服务并入它们的封装体内。然后保存该封装体以及其所有属性以便以后使用。该保存的封装体或者在工具内被检索并执行,或者作为一Web服务被导出以便可被其他应用使用(例如经由UDDI)。在该工具内执行还可用于调试目的。该工具在执行一个流时向用户提供信息反馈。例如,在封装体执行时,通过突出显示当前执行的Web服务来描述从Web服务到变换器到Web服务的事件的流。在一个实施例中,当Web服务执行时,代表该Web服务的可视图标是绿色的,当Web服务空闲时图标是白色的,而在Web服务检测到错误时图标是红色的。本发明提供了一种非编程装置,用于将Web服务组合(封装)起来,以开发可以是部分或全部应用、或者“超级”服务(然后可作为一个Web服务被提供的Web服务组合)的过程工作流。本发明提供了一种用于定义这些服务组合(封装体)的方法,从而可创建、查看和修改这些组合。(可视流构造器)。本发明提供了一种用于保存和检索这些封装体以便进行修改、分发(例如,分发给UDDI注册库或Web应用或产品)和/或执行(带有调试能力)的方法。本发明提供了一种用于在因特网(或互联网)或环境组合上执行具有可视反馈的过程工作流(封装体)的方法。系统以下面的方式创建Web服务图标。根据对Web服务的WSDL的分析,系统了解Web服务的(一个或多个)方法的签名和返回类型。然后,系统创建该方法的文字/图标表示。在一个实施例中,每个方法都是一多行的框。第一行是Web服务的名称,第二行是方法的名称和返回类型,第三行和余下的行(如果存在的话)代表输入参数的类型。创建本地Web服务目录Web服务封装体构造器提供了三种用于将可用的Web服务编目的方法。第一种方法是查询UDDI服务器(Web服务的事实上的目录)。第二种方法是借助于使用基于XML的文档的文件系统。第三种方法是通过在可视WSDL创建器中输入一服务的所有方面,来将该服务添加到本地目录中。不管使用什么方法,构建服务封装体是通过首先收集建立希望的流所需的所有服务来完成的。服务封装体构造器301的左边面板302是WSDL浏览器,其提供用于查看服务和可从这些服务得到的方法/功能的一般界面。可利用本
技术领域:
中已知的方法来创建可用Web服务的本地列表302。例如,可通过从可从一网站得到的中心列表中选择来手动地创建该列表。该列表可以层级分组的形式提供,以便易于导航。在一个实施例中,参照图4,定制的Web服务封装体浏览器工具从本地文件目录或经由HTTP或FTP或UDDI远程站点查询可用的WSDL文档,根据用户输入的标准来分析该些文档,并创建代表Web服务401-406的Web服务图标的列表302。每个Web服务(例如BlueMail402)可具有一个或一个以上暴露的方法,该方法由显示为该Web服务的子节点的方法图标(对于BlueMail402,为“*xsdstringsend...”)表示。例如,用户从该定制的Web服务浏览器中的菜单中选择File/ImportWSDL,浏览到一文档目录并选择Number2Text.wsdl。然后,系统读取该WSDL,对其进行分析,并创建一个具有getNumber2Text方法作为其子节点的Number2TextWeb服务节点。Number2TextWeb服务节点由一Web服务图标(铃铛)表示,而getNumber2Text方法由Web服务方法图标(球或*)302表示。构建封装体给定一填充了的服务列表302,则可开始封装体的构造。创建一新的Web服务封装体303完成了两方面的工作。首先,其提供了这样的空间(称为封装体画布),在该空间内可安排、链接。查看或测试单个服务,其次,该封装体用作该服务的命名的容器。即使可使用多个Web服务来定义一个封装体,但是封装体本身303代表了单个服务。因此,通过创建封装体303,就创建了一个Web服务,该Web服务的功能是其包含的服务501-503的流。参照图5,在将一Web服务图标拖放到新的封装体303的流构造区内之后,优选地创建一更详细的图标,该图标优选地包括两行或更多行。每行均提供一用于选择用于该Web服务的选项的GUI手段。选项可包括参数选择、文本个性化,或用于使一个以上的输入或输出与该Web服务图标互连的可选择的互连接触点。例如,“翻译器”Web服务502具有5行。第一行505是该Web服务的名称,在此情况下是“翻译器”。第二行506是方法的名称和返回类型,在此情况下,该名称为“翻译”,而该返回类型为“xsdstring”。第三行507到第五行509是方法签名,在此情况下为“xsdstringmtlang”507、“xsdstringtext”508、“xsdstringoption”509。“xsdstring”是输入参数的类型。Mtlang507是将要翻译成的语言。Text508是将翻译的文本。选项509是输出的格式,文本或HTML。例如,为了调用此Web服务以便将文本从英语翻译成西班牙语,用户需要右键点击第三行507,其生成一弹出窗口(未示出)。然后用户在该弹出窗口中将mtlang设定为Spanish。接下来,用户右键点击第四行508,并将文本设定为希望的词/句。最后,用户右键点击第五行509,将选项设定为“text”、“HTML”或让其空白。应理解,XSD是一XML前缀,其指示XML模式名称空间“www.w3.org/2001/XMLSchema”,并符合XML模式约定。“xsditem”,例如xsdstring,用于标识输入参数的类型或返回方法的类型。在用户将Web服务拖放到流面板(画布)内、连接这些Web服务并设定所需的输入参数之后,就创建了一封装体。在后台,还创建一代表Web服务对象以及Web服务之间的交互的图形数据结构。当用户从File菜单选择Save或Saveas时,使用Java对象串行化将该图形数据结构作为WSFL保存到硬盘中。在一个实施例中,保存的封装体可被添加到用户的Web服务菜单302中。将Web服务401-406从服务列表302拖放入封装体画布303会可视地实例化资源,并且在一优选实施例中为Web服务创建详细的图标。其由该服务的名称、从该服务504-517使用的功能、以及该服务运行所需的输入和输出表示。在此示例中,将“Number2Text”服务501拖入封装体画布303。此服务取得一个数字并用英语拼出该数字(例如,输入“1”变为输出“one”)。使用一个数字—在此情况下为号码1-来初始化Number2Text501。如果该封装体作为一个Web服务被调用(见调用/使用封装体),则也可指定此数字。然后,将翻译服务“翻译器”502拖入封装体画布303。将Number2Text501的输出连接到该翻译器的输入。手动地将该翻译器设置成将英语翻译成西班牙语。如果运行此封装体或服务流,则它会调用该Number2Text服务501并返回“one”。它会将该结果传给翻译器服务502并将“one”翻译成“uno”。在该流执行时,突出显示当前的服务,并且连接箭头用红色和绿色可视地指示成功和失败。可以可视地检查和分析从一个服务到另一个服务的流。随着封装体复杂性的增加,这被证明是非常有教益的。可利用多种本
技术领域:
内的技术人员熟悉的方法来实现执行可视化。可添加动画来显示在测试中的功能。可利用声音来扩充该可视表示,以进一步提高功能的可视化。例如在当前的示例中,动画人物例如行走的人形可将消息从图标传送到图标,同时被突出显示的图标或互连表现了正被可视化的项目。然后,计算机用话音消息如同动画人物在评论那样指示,例如当可行时指示“看起来很好”,当怀疑存在问题时指示“唔-哦”,或甚至指示描述可能的改正“你还没有告诉我在’翻译器’步骤中使用哪种语言”的话音消息。通过将“BlueMail”服务503(因特网邮件服务)拖入画布303,提供了一个将该流的结果用电子邮件发送给收信人的机制。在此情况下,将收件人(to)字段512设定为webahead@us.ibm.com。将发件人(from)字段515设定为Web服务封装体email-test.wsfl。将主题(subject)字段516设定为Number2TextTranslationTest。最后,将翻译器502的输出连接到电子邮件服务503的消息输入。在此时,运行该封装体可实现与上述相同的功能,不过另外还将结果用电子邮件发送给webahead@us.ibm.com。最后被拖到封装体的画布303中的项是可视报警修改器518。在一个实施例中,该可视的报警图标可从用户的工具栏411得到。在其他实施例中,用户的浏览器包括这样的本地程序的列表,该些本地程序可以与来自Web服务列表302中的Web服务相同的方式被拖入画布,并且添加到流中。修改器是交互地改变流的项目。在此示例中,报警修改器518仅利用邮件服务的结果输出生成一“报警”对话框。该修改器518将通过报警对话框将因特网邮件操作的成功或失败告知用户。其他的修改器可取得一字符串并将其转化为整数(例如“001”变为1)。调用/使用封装体对于完成的Web服务封装体303,可用三种方式中的任何一种调用它。第一种方式是手动运行。这涉及按下“play”按钮或类似物。第二种方式是以定期的方式调用封装体。例如,可每隔一个小时调用服务。第三种方式是通过SOAP服务器插件调用封装体。该SOAP服务器插件提供了两个功能。一个功能是能够作为UDDI服务器被查询。当客户请求所有开启的服务/封装体时,插件将返回遵循UDDI和WSDL标准的动态生成的响应。当查询服务器时,该服务器将发送封装体名称作为服务名称,作为由将被调用的第一服务确定的输入列表的输入,以及由最后一个服务的输出限定的输出。另一个功能是SOAP插件担当一接口来运行封装体,就好像封装体是Web服务似的。当外部客户请求SOAP服务器插件。后者转而调用指定的封装体时,会发生调用。通过这种方式,封装体可用作新封装体的组件。本发明的一个部分是IDSSOAP桥,其为IDS提供了类似的功能。IDS是基于封装体的报告环境。该IDSSOAP桥提供了对IDS的SOAP访问。由于该桥将其本身公告为Web服务,因此IDS封装体可被集成到封装体流中。参照图3,在优选实施例中,Web服务封装体构造器GUI301包括两个框架302、303。一个框架显示可用于构建新的封装体的可用服务的服务列表302。另一个框架显示封装体303,在封装体完成时其将包括来自第一个框架的互连的服务。参照图4,其示出服务列表302的一优选实施例的示例。该服务列表包括可用于封装的服务401-406。在一个实施例中,该些服务包括远程服务和本地Web服务的混合。可拖入容器的、该列表中的每个服务均由一图标指示。一些服务401、402、405还包括关于该服务的附加信息。参照图5,其示出已由本发明创建的示例性封装体303。已将三个Web服务501-503放入该封装体303,并且用户已将这三个服务互连。本地服务518已被放入并连接到第三个Web服务503的输出。参照图6,其示出服务流初始化。向UDDI服务器查询可用的服务(步骤601)。使用查询的结果,用候选的Web服务图标更新本地服务目录(步骤602)。用户可使用该本地服务目录来向服务列表302选择性地添加服务。一旦在封装体303中创建一新的服务流(步骤603),则将其保存在本地文件中以便将来使用(步骤604)。在优选实施例中,用基于XML的WSFL语言描述该新的流。将该命名的封装体可选地添加到服务列表302中,来作为一个可拖入新的封装体303的新服务流。图7中示出创建一服务流封装体的示例。在步骤701,在GUI显示301中打开新的封装体303。在步骤702,将第一服务拖放入该封装体303。在步骤703,将第二服务拖放入该封装体303。在步骤704,将该第一服务的输出连接到该第二服务的输入。在步骤705,选择用于该第二服务的选项。在步骤706,将第三服务拖放入该封装体303。在步骤707,将该第三服务的输入连接到该第二服务的输出。在步骤708,将第四服务拖放入该封装体并使该服务与第三服务相连接,该第四服务是一本地服务。该封装体完成。在步骤709,可手动地运行该封装体以验证其功能。图8示出服务流的执行。在步骤801,通过GUI显示打开并示出一服务流。可通过按下GUI“play”按钮420(在步骤802)或通过SOAP服务器插件(步骤803)来运行该服务流。图9示出示例性的Web服务流SOAP服务插件的操作。在步骤901,接收到对封装体的请求。在步骤902,对照本地已知的服务检查该名称空间。如果没有发现封装体,则报告异常。如果发现一封装体(步骤903)但是没有加载该封装体,则从该封装体的源加载该封装体(步骤905)。当加载了所请求的封装体时,可执行该封装体(步骤906),并返回该封装体的执行结果(步骤907)。图10示出Web服务流的WSDL生成。在步骤1001,接收到对命名的封装体的“WSDL”的请求。在步骤1002,对照已知的服务检查该名称空间。如果没有发现封装体(步骤1003),则报告异常。如果发现一封装体但是没有加载该封装体(步骤1004),则在步骤1005,加载该封装体。在步骤1006,可选地检查该封装体的输出和输入,并且在步骤1007,返回动态生成的“WSDL”。图11示出IDSSOAP桥流。在步骤1101,接收到对“IDS”操作的请求。在步骤1102,提交对“IDS”系统的操作请求。在步骤1103,返回“IDS”对象或指定的数据类型,并且在步骤1104,返回用于异步操作的可选的跟踪令牌。图12示出经由ISB获取异步请求。在步骤1204,接收到对经由跟踪令牌的“IDS”操作的请求。在步骤1205,检查“IDS”服务器操作。如果不允许经由该令牌的操作(步骤1206),则报告异常。如果允许经由该令牌的操作,则返回“IDS”对象或指定的数据类型(步骤1207)。在步骤1208,返回可选的完成百分比的信息。尽管对于理解本发明不是必须的,但是在附录A中提供了一示例性的实现。版权所有者并不反对相关专利事务所内的任何人进行摹真复制,然而在别的方面却保留所有版权权利。下面给出对该文档的简短描述Block.java==这个类提供了Web服务的构件块的基本实现。DragTree.java==这个类提供了可从其中拖动服务对象的树组件。FlowPane.jave==这个类实现了用户可在其中拖放Web服务对象或者设置该Web服务对象的属性的工作区。Link.java==这个类实现了Web服务对象之间的连接组件。Operation.java==这个类提供了Web服务方法调用的表示。ParamInputDialog.java==这个类提供了用于向Web服务方法调用设置参数的对话框。Service.java==代表一Web服务对象的核心类。WorkFlowFrame.java==这个类代表包含一个FlowPane的内部框架。WorkSpace.java==这个类代表包含工作流的集合的工作空间。提出了根据本发明创建的封装体的一些应用。在一个实施例中,经由网络协议例如SOAP、RPC、HTTP接收到的远程请求调用根据本发明的Web封装体。在另一个实施例中,封装体的元件并不阻止封装体的成功执行和/或对外部请求的响应。在另一个实施例中,通过为远程应用提供WSDL表示来将根据本发明的封装体集成到远程应用。这种WSDL可被动态生成。在另一个实施例中,图标与封装体修改器相结合。封装体修改器可表示逻辑非、与、或、异或、与非。此外,封装体修改器可包括并行、开关和数据连接。根据本发明的封装体Web服务由一个或多个资源(资源可以是其他Web服务、开关/并行路径以及其他“内置的”功能例如GUI报警或媒体播放)构成,所述封装体Web服务由于提供一种从外部(远程)资源调用封装体流的方法而被增强。下面的示例说明了远程系统/用户如何与本发明相交互来利用Web服务封装体流。从远程计算机调用一封装体流。该远程计算机使用网络协议与主机通信。在一优选的实现中,该远程计算机能够进行一连串“调用”,来请求可用的服务封装体的列表,和如何调用特定封装体的特定细节,或者进行调用封装体的实际请求。这些“调用”事务优选地是根据公开的当前技术标准的HTTP上的SOAP。远程计算机向封装体环境查询可用Web服务流的列表。远程计算机优选地向所有可用的封装体发送一个一般请求。此请求可选地更具体,例如仅请求例如所有以字母“A”开头的封装体。主机服务器返回的响应是与该初始请求相匹配的服务的列表。优选地,这可使用UDDI请求和响应来完成。在一个实施例中,远程计算机对在封装体环境中寄居的一特定封装体进行查询。远程计算机发送一个查询,该查询指定了用于该封装体服务的特定标识符。来自主机的响应是一个文档,该文档足够详细地定义了给定服务封装体的输入和输出,以随后向主机系统发送调用请求。优选地,该响应使用WSDL标准来完整地描述封装体期望的输入和输出。远程计算机调用在封装体环境中寄居的封装体服务流。该远程计算机指定其希望调用的特定封装体服务,和由先前的对服务描述(WSDL)的调用指定的所需的任何参数。对该调用请求的响应由该服务描述限定。在一优选的实现中,此事务使用HTTP上的SOAP和WSDL来通信和描述。例如计算机A查询计算机B,来请求所有可用的服务(封装体流)。计算机B以可用封装体Web服务流的列表作为响应。计算机A决定使用计算机B上的服务A。计算机A对计算机B进行适当的调用,来调用该封装体流(服务A)作为Web服务。计算机B执行该封装体流并将结果返回计算机A。在一个实施例中,本发明的Web封装体被外部集成,并且在客户机侧或在服务器侧被可视地设计、配置和管理。经由Web服务接口远程访问封装体优选地使用HTTP上的SOAP完成。在优选实现中,服务器模仿HTTP协议,适当地响应任何格式正确的请求。当一消息的目标是一封装体服务时,如果该消息不是一个格式正确的SOAP消息,则该服务器返回一错误。通过相同的用于构建封装体的拖放界面来管理此服务器的消息流。图13示出一ApacheWeb服务器的服务器事件流。这是服务器如何经常具有一系列步骤需要完成以生成响应的示例。与此类似的服务器或流都能够利用封装体的概念来提供高的可定制性和灵活性。对于流中的每一步骤,用户会将图标拖放到桌面上来完成此系统。例如,可开发一个定制的认证机制,其中将该机制拖放在打算发生认证的点上。另一个进行内容编码的图标,可被拖放在该流的末端。内容编码获取一组数据,并以特定方式将其编码。在此例中,它可应用压缩算法。此外,这些图标可实际表示和执行其他流。对于图13中所示的Apache流中的每一步骤,将代表一个模块。这个流被认为是线性流。参照图13,下面的一组事件说明了一个简单的HTTP流;接收消息1302,分析消息1304,检查被请求的资源,响应消息1310。当然,可使用由Rogers等人定义的封装体桌面来管理任何事件流。所提供的拖放模块之一可以是认证处理器。在一个优选实施例中,服务器流接收请求消息,对该消息解码,检查以确定资源存在,然后响应该请求。希望对某些请求限制访问。将认证处理器(模块)拖放到流内将提供此功能。该流变为接收请求1302,分析消息1304,检查认证1306,检查资源1308,然后响应1310。该流也可按不同的顺序进行接收请求,分析,检查响应,检查授权并然后响应。此外,如果需要的话,检查授权和检查资源可并行执行。响应模块1310将仅以这两个“检查”模块的结果作为输入,来确定合适的响应。如图13所示,请求1301被处理并变为阅读后的请求1302。在1303转换该请求,并在1304分析头部。在访问控制1305之后,在1306检查认证并在1307检查授权。检查文件Mime类型并且结果通过修正阶段。响应1310被发送给请求1301,并在1311被记入日志。在1312进行清除,并且在1313系统等待一个新请求。在每个阶段,如图所示在1311将过程记入日志。在一个实施例中,Web封装体在远程机器中运行。其他机器是群集的或网格使能的。在一个实施例中,已创建根据本发明的Web服务封装体,则在远程封装体使能的服务器上执行该封装体。用户将该封装体拖放到封装体桌面的一个区域内以使能网络连接。拖放仅是启动网络连接的一种方式。还可简单地创建一网络连接并发送请求。从本地桌面到远程服务器的通信包括使用网络协议到一个或多个服务器的网络连接。在一优选实现中,此网络连接将使用HTTP上的SOAP。远程服务器被单独表示为或组合为一个一般“服务器以太”(serverether)。用户将选择的封装体流拖放到表示一个单独的远程服务器或群集的组的图标上。这启动一个网络请求以处理该Web服务封装体。在一个优选实现中,群集的组随机地选择一个服务器以在其上执行该封装体,或者可选地在每个服务器上执行该封装体。然后将封装体发送给远程服务器以便执行。在一个优选实现中,该封装体是在XML消息中描述的,该消息包括必要组件的身份,将调用哪些Web服务,可在何处发现这些Web服务,将以什么顺序调用它们以及将哪些结果传送给哪些Web服务。在一个实施例中,所述结果是在流中最后执行的服务的结果。这类似于远程访问封装体的情况。在另一个实施例中,该结果可以是捕获了该流的每个请求和响应消息的文档,从而可在本地机器上严格地重放这些事件。在一个优选实现中,后面的响应也被以XML编码,并包含具有时间编码以精确地捕获被远程执行的流的原始SOAP包封。在一个实施例中,Web服务流顺序执行(如在图14中的封装体中所示)。单个记录1401向求和图标1402提供信息,然后向均值图标1403并最终向中值图标1404提供信息,并且由结果图标1405提供结果。每个图标均被个性化以执行所需的功能,包括“null”,其将记录传递到下一个阶段。在一个实施例中,Web服务流并行地执行。此功能由封装体修改器提供。在一个实施例中,提供一并行执行修改器(图14)。给定单个Web服务调用1501,随后可有多条并行路径。然后在1505,或者通过另一个Web服务调用/封装体或者经由一数据规范器来吸收一个或多个路径的结果。数据规范器获取多个数据输入并以可用的方式格式化该数据。例如,如果求一组数据的和1502、中值1504和均值1503,并且并行计算,一优选的规范器1505可被配置为仅存储最低值。在另一个实施例中,来自所有路径的结果1506被存储,作为该服务调用的最终值。在一优选实现中,该结果1506为一XML文档,其代表由封装体流的结果定义的数据结构。在一优选实现中,任何上述修改器中遵循由封装体环境提供的其他窗口小部件的模式,例如报警对话框。更复杂的流可能包括并行功能(图15)。图15示出在同一组数据上执行的一组统计操作。在此情况下,求和、中值和均值是打算在单独一组数据上运行的单独的Web服务。该数据没有改变,并且来自一个服务的输出不作为输入流入另一个服务。该封装体已被安排为并行执行Web服务。这通过将初始输入连接到每个服务上来实现。其结果是合并功能的输入,该合并功能使数据相结合。并行执行可优化封装体的总性能。在一个实施例中,通过使用GUI显示指点设备例如鼠标画出互连线来使图标互连。在另一个实施例中,通过在显示工具栏上选择互连功能或利用每个图标具有的手段,来使图标互连。在一个实施例中,使用一修改器块1506。在图15的示例中,修改器块是被拖到封装体中的图标。第一图标1501连接到该块的输入A,该块的输出C、D和E连接到它们各自的块1502-1504。这种块可具有多个输入和多个输出。该块可具有预定的功能(互连),或者可以是实现转换、过滤、监控或除了流互连之外的任意多个有用服务的功能图标。用户可在适当时拖放多个服务图标,并使起始输入连接到多个分支。使用数据合并修改器或其他Web服务封装体,可将该些分支的输入合并成单个结果。在一个实施例中,此结果为一XML。当需要在相同或不同的数据集上执行多个操作时,可获得进一步的功能分配。图16示出使多组数据需要同样的统计生成的解决方案。因为数据集的数量大于1,所以流可利用其他封装体服务器以执行最初的并行查询。这利用了封装体流中的并行功能,但是也将服务封装体执行分配到多个封装体服务器上。在另一个实施例中,执行的Web服务流带有开关功能。此功能由封装体修改器提供。在一个实施例图18中,提供了开关修改器1802。该开关修改器1802检查给定变量或事件的状态,以确定在哪个路径上继续执行。例如,Web服务调用的结果是三个不同值之一。根据此调用的值将遵循不同的执行路径。例如,结果A分支到第一路径,结果B分支到第二路径而结果C转到第三路径。还存在其他的可能性,并且本发明决不是由此示例限制。在图18的示例中,将记录1801提供给开关1802,该开关确定是否执行作图或求和操作。此开关然后根据开关1802的个性化,来将消息发送给求和图标1803或作标1804(或这两个图标)。在1805,合并且报告该结果。开关功能提供了另一种根据流的值或状态控制封装体的分支的方法(图18)。给定另一个统计示例,可使输入的请求指示数据的求和或图形表示。使用该开关修改器,提供了一种与其中执行每个路径的并行功能不同的分支机制。开关提供了能够返回多个结果的单个封装体。此外,其使得流设计者能够在存在特定条件的情况下执行不同的分支。例如,封装体设计者可决定应根据一天中的时间来执行不同的分支。封装体设计者生成它们的流,并使用开关修改器来连接它们。可设定封装体修改器中的条件以检测时间为AM还是PM。根据其结果,执行分支中的一个。该示例是一个简单化的示例,但是说明了该开关可由任意数量的事件、其他封装体的输出、时间以及作为执行的一部分传递的参数触发这一点。在另一个实施例图16中,记录1601可与在另一条路径中顺序执行(求和1612、均值1613,然后中值1614)的其他记录并行地由任何一条路径顺序执行(求和1602、均值1603,然后中值1604)。在另一个实施例中,通过向并行图标1702、1703、1704提供多条互连线来指示记录1701的并行执行,并且通过将该些并行图标的输出提供给结果图标1705来合并1705该结果。尽管已示出和说明了本发明的优选实施例,但是应理解,本发明并不局限于文中所公开的准确结构,并且“保留”在所附权利要求限定的本发明的范围内进行一切改变和修改的权利。附录//Copyright(c)2001IBMpackagecom.ibm.webahead.flow;importjava.awt.Point;importjava.io.Serializable;/***该类提供了Web服务的构件块的基本实现。*/publicabstractclassBlockextendsObjectimplementsSerializable{ intx; inty; LinkoutLink; booleanrunning=false; finalstaticintmarginLeft=6; finalstaticintmarginTop=3; /** *构造函数 */ publicBlock(){ } publicvoidsetLoc(intx,inty){ this.x=x; this.y=y; }<!--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.*;/***该类提供了可从其拖出服务对象的树组件。*/publicclassDragTree extendsJTree implementsTreeSelectionListener,DragGestureListener,DragSourceListener{/**存储组件的父框架*/privateWorkFrameparent=null;/**存储选择的节点信息*/protectedTreePathSelectedTreePath=null;protectedDefaultMutableTreeNodeSelectedNode=null;/**拖动所需变量*/privateDragSourcedragSource=null;privateDragSourceContextdragSourceContext=null;<!--SIPO<DPn="22">--><dpn="d22"/> privatePointcursorLocation=null; /**构造函数 @paramroot树的根节点 @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,//指定合法动作 this//DragGestureListener); /*取消鼠标右键点击作为合法动作-如果为JTree实现了 *JPopupMenu,则特别有用 */ dgr.setSourceActions(dgr.getSourceActions()&~InputEyent.BUTTON3_MASK); //不必要,但给出了文件管理器的外观 putClientProperty(″JTree.lineStyle″,″Angled″); //MetalTreeUIui=(MetalTreeUI)getUI();) } /**返回所选节点*/ publicDefaultMutableTreeNodegetSelectedNode(){ returnSelectedNode; }<!--SIPO<DPn="23">--><dpn="d23"/> /////////////////////////接口代码//////////////////// /**DragGestureListener接口方法*/ publicvoiddragGestureRecognized(DragGestureEvente){ //获得所选节点 DefaultMutableTreeNodedragNode=getSelectedNode(); if(dragNode!=null&&dragNode.isLeaf()){ //获得Transferable对象 Transferabletransferable=(Operation)dragNode.getUserObject(); try{ ((FlowPane)parent.getSelectedFrame().getContentPane()).setOutsiderDrop(true); }catch(java.lang.NullPointerExceptionne){ System.out.println(″nointernalframe,notdragged″); } //开始拖动 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接口方法。这有点难看。这是根据是否允许 *放Transferable对象而设置光标的地方。然而,需要有鼠标的位 *置和设置光标的对象,这两者来自两个不同的事件。尽管它不漂 *亮,但使用DropTargetListenerdragOver方法中的位置设置一 *全局变量。 */ voidsetCursor(DragSourceDragEventdsde){ /*//如果不知道光标位置,则什么也不做。 if(cursorLocation==null)return; TreePathdestinationPath=getPathForLocation(cursorLocation.x,cursorLocation.y); //获得设置鼠标类型的对象<!--SIPO<DPn="25">--><dpn="d25"/> DragSourceContextdsc=dsde.getDragSourceContext(); //如果目标路径可行,则设置光标以允许放... if(testDropTarget(destinationPath,SelectedTreePath)==null) dsc.setCursor(DragSource.DefaultCopyDrop); //...否则设置不允许放 elsedsc.setCursor(DragSource.DefaultCopyNoDrop); */ } /**TreeSelectionListener-设置所选节点*/ 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.*;/***该类实现用户可在其中拖放Web服务对象或设置Web服务对象的属*性的工作区。*/publicclassFlowPaneextendsContainer implementsDropTargetListener, DragGestureListener, DragSourceListener, ActionListener/*,鼠标侦听器*/{ 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;//如果从左侧树拖动 booleanmovingDrop;//如果标题栏被拖动则为真 intdragFromX,dragFromY; /**拖动所需变量*/ privateDragSourcedragSource=null; privateDragSourceContextdragSourceContext=null; /** *构造函数 */ 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(″设置值″)); 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(″设置过滤器″)); 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结束 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!=null结束 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){ //设置光标位置。setCursor方法中需要 } /**DropTaregetListener接口方法*/ publicvoiddropActionChanged(DropTargetDragEvente){ } /**DropTargetListener接口方法-释放拖动时做什么*/ publicvoiddrop(DropTargetDropEvente){ //只放在具有焦点的内部框架上 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)){ //转换到适当的数据类型 try{ dragedBlock=(Operation)tr.getTransferData(Operation.OPERATION_FLAVOR); }catch(Exceptionexc){ exc.printStackTrace(); e.dropComplete(true); return; } //System.out.println(″dragedOperation=″+dragedOper); //获得新位置 Pointloc=e.getLocation(); //获得节点 //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!=null) JOptionPane.showMessageDialog(this,msg); } } //适当展开节点-可能这不是最好的方法... }elseif(tr.isDataFlavorSupported(XMLFilter.XMLFILTER_FLAVOR)){ try{ //转换到适当的数据类型 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!=null) JOptionPane.showMessageDialog(this,msg); } } }elseif(tr.isDataFlavorSupported(Presenter.PRESENTER_FLAVOR)){ try{ //转换到适当的数据类型 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()!=null) 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″); }//方法结束 publicvoidpaint(Graphicsg){ super.paint(g); Vectoropers=workflow.getOperationVec(); for(inti=0;i<opers.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); } } ///////拖动代码///////////////////// /**DragGestureListener接口方法*/ publicvoiddragGestureRecognized(DragGestureEvente){ //获得所选操作 Blockblock=workflow.select(e.getDragOrigin().x,e.getDragOrigin().y); if(block!=null){ setOutsiderDrop(false); if(block.isDragingTitle(e.getDragOrigin().x,e.getDragOriginO.y)){//移动框 movingDrop=true; dragFromX=e.getDragOrigin().x; dragFromY=e.getDragOrigin().y; //开始拖动 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;}////鼠标侦听器///////*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){ //确定选择了哪个菜单项 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!=null) 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!=null)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.*;/***该类实现在Web服务对象间的连接组件。*/publicclassLinkextendsObjectimplementsSerializable{BlockfromBlock;<!--SIPO<DPn="43">--><dpn="d43"/>BlocktoBlock;//Presenterpresenter;inttoIndex;booleanrunning=false;staticfinalintrange=5;staticfinalintARROW_SIDE=8;//箭头大小staticfinalintARROW_HEIGHT=10;/***构造函数*/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!=null)?toBlock.getInPoint(toIndex).xpresenter.getInPoint().x; //inty2=(toBlock!=null)?toBlock.getInPoint(toIndex).ypresenter.getInPoint().y; intx2=toBlock.getInPoint(toIndex).x; inty2=toBlock.getInPoint(toIndex).y; //处理x1=x2时的情况 if(x1==x2){ if(py>=Math.min(y1,y2)&&py<=Math.max(y1,y2)&&Math.abs(px-x1)<=range) returnthis; elsereturnnull; }elseif(y1=y2){ 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=y1+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;}/***从点pFrom到点pTo绘制箭头。*/privatevoiddrawArrow(Graphicsg,PointpFrom,PointpTo){ doubleslope; intborderSpace=2; doublefx,fy,tx,ty; /*(x1,y1)(centerX,centerY)左边的点*/ /*(x2,y2)(centerX,centerY)右边的点*/ 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;//中点具有与pFrom、pTo相同的x。 if(ty>=fy)//箭头向下。<!--SIPO<DPn="49">--><dpn="d49"/> centerY=ty-ARROW_HEIGHT; else//箭头向上。 centerY=ty+ARROW_HEIGHT; y1=centerY; y2=centerY; x1=centerX-(int)ARROW_SIDE/2; x2=centerX+(int)ARROW_SIDE/2; }elseif(ty==fy){//水平线。 centerY=ty;//中点具有与pFrom、pTo相同的y。 if(tx>=fx)//箭头向右。 centerX=tx-ARROW_HEIGHT; else//箭头向左。 centerX=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服务方法调用的表示。*/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; /** *构造函数 */ 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; 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); } /**实现Transferable接口*/ publicObjectgetTransferData(DataFlavordf)throwsUnsupportedFlavorException,IOException{ if(df.equals(OPERATIONFLAVOR)){ returnthis; }else{ thrownewUnsupportedFlavorException(df); } } /**实现Transferable接口*/ publicDataFlavor[]getTransferDataFlavors(){ returnflavors; } /*publicvoidsetLoc(intx,inty){ this.x=x; this.y=y; 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); //发现框的宽度 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; //绘制标题 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(),Font.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+(i+2)*recH; //if(inLink!=null&&inLinkEil!=null‖paramValues[i]!=null) drawConnector(x,curY,width,recH,″in″,g); g.draw3DRect(x,curY,width,recH,true); if(this.paramValues[i]!=null) 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&&posY<=y+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&&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; //构建调用 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); //进行调用注意actionURI为空,因为XML-SOAPrpcrouter //不需要它。这在未来可能改变。 Responseresp=null; try{ resp=call.invoke(/*routerURL*/url,/*actionURI*/″″); }catch(org.apache.soap.SOAPExceptione){ returne.getMessage(); } //检查响应。 if(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服务方法调用设置参数的对话框。*/publicclassParamInputDialogextendsJDialog{ privateStringtypedText=null; privateJOptionPaneoptionPane; /** *构造函数 */ 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){ /* *不是直接关闭窗口,而是改变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的值。如果不这样,则当用户 //下次按下同一个键时,将不会触发属性改变事件。 optionPane.setValue (JOptionPane.UNINITIALIZED_VALUE); if(value.equals(btnStringl)){ typedText=textField.getText(); }else{//用户关闭对话框或点击取消。 typedText=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服务对象的核心类。*/publicclassServiceextendsObjectimplementsSerializable{ Stringname; Stringurn; Stringurl; VectoroperationVec; /** *构造函数 */ 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!=null&&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<operations.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; } //已经分析了文档,现在打印它。 //获得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.*;/***该类代表包含一个工作流的内部框架。*/publicclassWorkFlowFrameextendsJInternalFrame//实现DropTargetListener{WorkFrameparent; WorkFlowworkflow; /** *构造函数 */ 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; /** *构造函数 */ 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(″errorinconstructing″+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<operVec.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(″errorinconstructing″+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<operVec.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(″errorinconstructing″+url); e.printStackTrace(); break; } serviceVec.addElement(service); DefaultMutableTreeNodenode=new<!--SIPO<DPn="83">--><dpn="d83"/>DefaultMutableTreeNode(service,true); VectoroperVec=service.getOperationVec(); for(intj=0;j<operVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } root.add(node); } } voidaddWSDL(DefaultTreeModeltreemodel,File[]files){ for(inti=0;i<files.length;i++){ Filefile=files[i]; Serviceservice=null; try{ service=newService(files[i]); }catch(Exceptione){ System.out.println(″errorinconstructing″+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<operVec.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(″errorinconstructing″+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<operVec.size();j++){ DefaultMutableTreeNodechild=newDefaultMutableTreeNode(operVec.elementAt(j),false); node.add(child); } treemodel.insertNodeInto(node,root,root.getChildCount()); } } DefaultMutableTreeNodegetRoot(){ returnroot; } voiddeleteService(DefaultTreeModeltreemodel,DragTreetree){ if(treemodel!=null&&tree!=null&&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; }}权利要求1.一种用于在Web服务环境中创建计算机程序的方法,该方法包括以下步骤将第一Web服务程序的第一表示移动到一GUI显示分区内;将第二程序的第二表示移动到该GUI显示分区内;以及使用GUI功能将该第一表示与第二表示互连,其中该第一Web服务程序与该第二程序可编程地通信以执行希望的操作。2.根据权利要求1的方法,还包括以下步骤使用GUI功能选择第一表示或第二表示中的任何一个;以及使用GUI功能设定所选择的表示的参数。3.根据权利要求1的方法,其中,所述GUI功能包括鼠标、鼠标按钮、键盘、触摸屏、触控板、语音识别技术、光标定位或光笔中的任何一个。4.根据权利要求1的方法,其中,所述第一表示或第二表示中的任何一个是显示的图标。5.根据权利要求1的方法,其中,移动所述表示的功能是拖放。6.根据权利要求2的方法,其中,所述设定参数的步骤还包括以下步骤使用GUI功能启动参数选项的显示;根据预定的计划在该参数选项的显示上进行操作;以及退出该参数选项的显示。7.根据权利要求1的方法,还包括以下步骤启动对所述互连的表示的检测;以及突出显示所述第一表示以指示功能状态。8.根据权利要求7的方法,其中,所述突出显示指示空闲、工作、错误或警告中的任何一个。9.根据权利要求7的方法,其中,所述突出显示是通过颜色、亮度、文本消息、形状改变或音频消息中的任何一个来实现的。10.根据权利要求1的方法,还包括以下步骤将所述第一和第二表示以及互连保存为一封装体表示。11.根据权利要求10的方法,其中,所述封装体表示被放置在用户的菜单上作为程序的第三表示。12.根据权利要求1的方法,还包括以下步骤创建所述第一Web服务的第一表示,以及将所创建的第一表示放置在用户的菜单上。13.根据权利要求12的方法,其中,从所述用户菜单、网页或系统创建的下拉菜单中的任何一个移动所述第一表示。14.根据权利要求1的方法,其中,从由所述Web服务提供的WSDL创建所述第一表示。15.根据权利要求1的方法,其中,所述互连步骤包括UDDI集成。16.根据权利要求1的方法,其中,所述希望的操作包括创建音频文件、视频文件、文本可查看文件、外部程序执行、图形用户界面改变或图形用户界面对话框中的任何一个。17.根据权利要求1的方法,其中,所述第二程序是Web服务程序。18.一种用于在Web服务环境中创建计算机程序的计算机程序产品,该计算机程序产品包括具有计算机可读程序代码的计算机可读介质,所述程序代码包括用于将第一Web服务程序的第一表示移动到一GUI显示分区内的计算机可读程序代码;用于将第二程序的第二表示移动到该GUI显示分区内的计算机可读程序代码;以及用于使用GUI功能将该第一表示与第二表示互连的计算机可用于使用GUI功能将该第一表示与第二表示互连的计算机可读程序代码,其中该第一Web服务程序与该第二程序可编程地通信以执行希望的操作。19.根据权利要求18的计算机程序产品,还包括以下步骤用于使用GUI功能选择所述第一表示或第二表示中的任何一个的计算机可读程序代码;以及用于使用GUI功能设定所选择的表示的参数的计算机可读程序代码。20.根据权利要求18的计算机程序产品,其中,所述GUI功能包括鼠标、鼠标按钮、键盘、触摸屏、触控板、语音识别技术、光标定位或光笔中的任何一个。21.根据权利要求18的计算机程序产品,其中,所述第一表示或第二表示中的任何一个是显示的图标。22.根据权利要求18的计算机程序产品,其中,移动所述表示的计算机可读程序代码包括拖放。23.根据权利要求18的计算机程序产品,其中,所述设定参数的计算机可读程序代码还包括用于使用GUI功能启动参数选项的显示的计算机可读程序代码;用于根据预定的计划在该参数选项的显示上进行操作的计算机可读程序代码;以及用于退出该参数选项的显示的计算机可读程序代码。24.根据权利要求18的计算机程序产品,还包括用于启动对所述互连的表示的检测的计算机可读程序代码;以及用于突出显示所述第一表示以指示功能状态的计算机可读程序代码。25.根据权利要求24的计算机程序产品,其中,所述突出显示指示空闲、工作、错误或警告中的任何一个。26.根据权利要求24的计算机程序产品,其中,所述突出显示是通过颜色、亮度、文本消息、形状改变或音频消息中的任何一个来实现的。27.根据权利要求18的计算机程序产品,还包括用于将所述第一和第二表示以及互连保存为一封装体表示的计算机可读程序代码。28.根据权利要求27的计算机程序产品,其中,所述封装体表示被放置在用户的菜单上作为程序的第三表示。29.根据权利要求18的计算机程序产品,还包括用于创建所述第一Web服务的第一表示的计算机可读程序代码,以及用于将所创建的第一表示放置在用户的菜单上的计算机可读程序代码。30.根据权利要求29的计算机程序产品,其中,从所述用户菜单、网页或系统创建的下拉菜单中的任何一个移动所述第一表示。31.根据权利要求18的计算机程序产品,其中,从由所述Web服务提供的WSDL创建所述第一表示。32.根据权利要求18的计算机程序产品,其中,所述用于互连的计算机可读程序代码包括用于UDDI集成的计算机可读程序代码。33.根据权利要求18的计算机程序产品,其中,所述希望的操作包括创建音频文件、视频文件、文本可查看文档、外部程序执行、图形用户界面改变或图形用户界面对话框中的任何一个。34.根据权利要求18的计算机程序产品,其中,所述第二程序是Web服务程序。35.一种用于在Web服务环境中创建计算机程序的系统,该系统包括以下装置将第一Web服务程序的第一表示移动到一GUI显示分区内的移动器;将第二Web服务程序的第二表示移动到该GUI显示分区内的移动器;以及使用GUI功能将该第一表示与第二表示互连的互连器,其中该第一Web服务程序与该第二程序可编程地通信以执行希望的操作。36.根据权利要求35的系统,还包括使用GUI功能选择第一表示或第二表示中的任何一个的选择器;以及使用GUI功能设定所选择的表示的参数的参数设定器。37.根据权利要求35的系统,其中,所述GUI功能包括鼠标、鼠标按钮、键盘、触摸屏、触控板、语音识别技术、光标定位或光笔中的任何一个。38.根据权利要求35的系统,其中,所述第一表示或第二表示是显示的图标。39.根据权利要求35的系统,其中,移动所述表示的功能是拖放。40.根据权利要求36的系统,其中,所述参数设定器还包括使用GUI功能启动参数选项的显示的显示启动器;根据预定的计划在该参数选项的显示上进行操作的操作器;以及退出该参数选项的显示的退出器。41.根据权利要求35的系统,还包括启动对所述互连的表示的检测的启动器;以及突出显示所述第一表示以指示功能状态的修改器。42.根据权利要求41的系统,其中,所述突出显示指示空闲、工作、错误或警告中的任何一个。43.根据权利要求41的系统,其中,所述突出显示是通过颜色、亮度、文本消息、形状改变或音频消息中的任何一个来实现的。44.根据权利要求35的系统,还包括将所述第一和第二表示以及互连保存为一封装体表示的表示保存器。45.根据权利要求44的系统,其中,所述封装体表示被放置在用户的菜单上作为程序的第三表示。46.根据权利要求35的系统,还包括创建第一Web服务的第一表示的创建器,以及将所创建的第一表示放置在用户的菜单上的菜单放置器。47.根据权利要求45的系统,其中,从用户菜单、网页或系统创建的下拉菜单中的任何一个移动所述第一表示。48.根据权利要求35的系统,其中,从由Web服务提供的WSDL创建所述第一表示。49.根据权利要求35的系统,其中,所述互连器还包括UDDI集成。50.根据权利要求35的系统,其中,所述希望的操作包括创建音频文件、视频文件、文本可查看文件、外部程序执行、图形用户界面改变或图形用户界面对话框中的任何一个。51.根据权利要求35的系统,其中,所述第二程序是Web服务程序。全文摘要本发明提供了一种用于从Web服务建立程序的图形用户界面(GUI)接口。该与Web服务的接口在用户菜单中优选地由图标和文本表示。用户将代表Web服务的图标从菜单拖放到显示区域,并将该图标与代表其他程序实体(优选地为其他Web服务)的其他图标互连。优选地,在拖放之后在该显示区域内创建一更详细的图标。将在该显示区域内完成的互连图标的集合保存为一个新的程序实体。本发明还包括在测试模式下使通过模型的信息流可视化。文档编号G06F9/44GK1761943SQ200480007469公开日2006年4月19日申请日期2004年3月17日优先权日2003年4月2日发明者B·古德曼,J·凯宾格,K·拉加德,R·罗杰斯,舒晨申请人:国际商业机器公司