精彩的人生

          好好工作,好好生活

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

          #

          Building Web Services the REST Way

          Roger L. Costello

          I will first provide a brief introduction to REST and then describe how to build Web services in the REST style.

          What is REST?

          REST is a term coined by Roy Fielding in his Ph.D. dissertation [1] to describe an architecture style of networked systems. REST is an acronym standing for Representational State Transfer.

          Why is it called Representational State Transfer?

          The Web is comprised of resources. A resource is any item of interest. For example, the Boeing Aircraft Corp may define a 747 resource. Clients may access that resource with this URL:

          http://www.boeing.com/aircraft/747
          
          A representation of the resource is returned (e.g., Boeing747.html). The representation places the client application in a state. The result of the client traversing a hyperlink in Boeing747.html is another resource is accessed. The new representation places the client application into yet another state. Thus, the client application changes (transfers) state with each resource representation --> Representational State Transfer!

          Here is Roy Fielding's explanation of the meaning of Representational State Transfer:

          "Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use."

          Motivation for REST

          The motivation for REST was to capture the characteristics of the Web which made the Web successful. Subsequently these characteristics are being used to guide the evolution of the Web.

          REST - An Architectural Style, Not a Standard

          REST is not a standard. You will not see the W3C putting out a REST specification. You will not see IBM or Microsoft or Sun selling a REST developer's toolkit. Why? Because REST is just an architectural style. You can't bottle up that style. You can only understand it, and design your Web services in that style. (Analogous to the client-server architectural style. There is no client-server standard.)

          While REST is not a standard, it does use standards:
          • HTTP
          • URL
          • XML/HTML/GIF/JPEG/etc (Resource Representations)
          • text/xml, text/html, image/gif, image/jpeg, etc (MIME Types)

          The Classic REST System

          The Web is a REST system! Many of those Web services that you have been using these many years - book-ordering services, search services, online dictionary services, etc - are REST-based Web services. Alas, you have been using REST, building REST services and you didn't even know it.

          REST is concerned with the "big picture" of the Web. It does not deal with implementation details (e.g., using Java servlets or CGI to implement a Web service). So let's look at an example of creating a Web service from the REST "big picture" perspective.

          Parts Depot Web Services

          Parts Depot, Inc (fictitious company) has deployed some web services to enable its customers to:
          • get a list of parts
          • get detailed information about a particular part
          • submit a Purchase Order (PO)
          Let's consider how each of these services are implemented in a RESTful fashion.

          Get Parts List

          The web service makes available a URL to a parts list resource. For example, a client would use this URL to get the parts list:

          http://www.parts-depot.com/parts
          
          Note that "how" the web service generates the parts list is completely transparent to the client. All the client knows is that if he/she submits the above URL then a document containing the list of parts is returned. Since the implementation is transparent to clients, Parts Depot is free to modify the underlying implementation of this resource without impacting clients. This is loose coupling.

          Here's the document that the client receives:

          <?xml version="1.0"?>
          <p:Parts xmlns:p="http://www.parts-depot.com" 
                   xmlns:xlink="http://www.w3.org/1999/xlink">
                <Part id="00345" xlink:/>
                <Part id="00346" xlink:/>
                <Part id="00347" xlink:/>
                <Part id="00348" xlink:/>
          </p:Parts>
          
          [Assume that through content negotiation the service determined that the client wants the representation as XML (for machine-to-machine processing).] Note that the parts list has links to get detailed info about each part. This is a key feature of REST. The client transfers from one state to the next by examining and choosing from among the alternative URLs in the response document.

          Get Detailed Part Data

          The web service makes available a URL to each part resource. Example, here's how a client requests part 00345:

          http://www.parts-depot.com/parts/00345
          
          Here's the document that the client receives:

          <?xml version="1.0"?>
          <p:Part xmlns:p="http://www.parts-depot.com"   
                  xmlns:xlink="http://www.w3.org/1999/xlink">
                <Part-ID>00345</Part-ID>
                <Name>Widget-A</Name>
                <Description>This part is used within the frap assembly</Description>
                <Specification xlink:/>
                <UnitCost currency="USD">0.10</UnitCost>
                <Quantity>10</Quantity>
          </p:Part>
          
          Again observe how this data is linked to still more data - the specification for this part may be found by traversing the hyperlink. Each response document allows the client to drill down to get more detailed information.

          Submit PO

          The web service makes available a URL to submit a PO. The client creates a PO instance document which conforms to the PO schema that Parts Depot has designed (and publicized in a WSDL document). The client submits PO.xml as the payload of an HTTP POST.

          The PO service responds to the HTTP POST with a URL to the submitted PO. Thus, the client can retrieve the PO any time thereafter (to update/edit it). The PO has become a piece of information which is shared between the client and the server. The shared information (PO) is given an address (URL) by the server and is exposed as a Web service.

          Logical URLs versus Physical URLs

          A resource is a conceptual entity. A representation is a concrete manifestation of the resource. This URL:
          http://www.parts-depot.com/parts/00345
          
          is a logical URL, not a physical URL. Thus, there doesn't need to be, for example, a static HTML page for each part. In fact, if there were a million parts then a million static HTML pages would not be a very attractive design.

          [Implementation detail: Parts Depot could implement the service that gets detailed data about a particular part by employing a Java Servlet which parses the string after the host name, uses the part number to query the parts database, formulate the query results as XML, and then return the XML as the payload of the HTTP response.]

          As a matter of style URLs should not reveal the implementation technique used. You need to be free to change your implementation without impacting clients or having misleading URLs.

          REST Web Services Characteristics

          Here are the characteristics of REST:
          • Client-Server: a pull-based interaction style: consuming components pull representations.
          • Stateless: each request from client to server must contain all the information necessary to understand the request, and cannot take advantage of any stored context on the server.
          • Cache: to improve network efficiency responses must be capable of being labeled as cacheable or non-cacheable.
          • Uniform interface: all resources are accessed with a generic interface (e.g., HTTP GET, POST, PUT, DELETE).
          • Named resources - the system is comprised of resources which are named using a URL.
          • Interconnected resource representations - the representations of the resources are interconnected using URLs, thereby enabling a client to progress from one state to another.
          • Layered components - intermediaries, such as proxy servers, cache servers, gateways, etc, can be inserted between clients and resources to support performance, security, etc.

          Principles of REST Web Service Design

          1. The key to creating Web Services in a REST network (i.e., the Web) is to identify all of the conceptual entities that you wish to expose as services. Above we saw some examples of resources: parts list, detailed part data, purchase order.

          2. Create a URL to each resource. The resources should be nouns, not verbs. For example, do not use this:

          http://www.parts-depot.com/parts/getPart?id=00345
          
          Note the verb, getPart. Instead, use a noun:

          http://www.parts-depot.com/parts/00345
          
          3. Categorize your resources according to whether clients can just receive a representation of the resource, or whether clients can modify (add to) the resource. For the former, make those resources accessible using an HTTP GET. For the later, make those resources accessible using HTTP POST, PUT, and/or DELETE.

          4. All resources accessible via HTTP GET should be side-effect free. That is, the resource should just return a representation of the resource. Invoking the resource should not result in modifying the resource.

          5. No man/woman is an island. Likewise, no representation should be an island. In other words, put hyperlinks within resource representations to enable clients to drill down for more information, and/or to obtain related information.

          6. Design to reveal data gradually. Don't reveal everything in a single response document. Provide hyperlinks to obtain more details.

          7. Specify the format of response data using a schema (DTD, W3C Schema, RelaxNG, or Schematron). For those services that require a POST or PUT to it, also provide a schema to specify the format of the response.

          8. Describe how your services are to be invoked using either a WSDL document, or simply an HTML document.

          Summary

          This article described REST as an architectural style. In fact, it's the architectural style of the Web. REST describes what makes the Web work well. Adhering to the REST principles will make your services work well in the context of the Web.

          In a future article I will write about the evolution of the Web using the REST principles.

          Acknowledgement

          Thanks to Robert Leftwich and Philip Eskelin for their very helpful comments in creating this document.

          References

          [1] http://www.ebuilt.com/fielding/pubs/dissertation/top.htm


          原文:http://www.xfront.com/REST-Web-Services.html

          posted @ 2006-08-31 17:17 hopeshared 閱讀(521) | 評論 (0)編輯 收藏

          市長熱線:12345 ? 65128088 ? ? ?
          反扒熱線:64011327 ? ? ? ? ? ?
          火警:119 ? ? ? ? ? ? ? ?
          交通傷急救熱線:68455655 ? 68455665 ?
          中毒援助熱線:83163388 ? 83160233 ?
          抗癌互助熱線:68276491 ? ? ? ? ? ?
          查號臺:114 ? ? ? ? ? ? ? ?
          移動電話話費(fèi)查詢臺:1861 ? ? ? ? ? ? ? ?
          鐵路查詢售票信息:2586 ? ? ? ? ? ? ? ?
          市燃?xì)饧瘓F(tuán)公司24小時(shí)熱線電話:65940469 ? 66510382
          北京市煤氣公司急修:65022414 ? ? ? ? ? ?
          北京市供電局報(bào)修中心:63129999 ? ? ? ? ? ?
          公證咨詢專線:98148 ? ? ? ? ? ? ?
          節(jié)水服務(wù)熱線:64200960 ? 64200972 ?
          特快專遞服務(wù)臺:185 ? ? ? ? ? ? ? ?
          報(bào)時(shí):12117 ? ? ? ? ? ? ?
          氣象綜合信息服務(wù)臺:211 ? ? ? ? ? ? ? ?
          首都公眾信息網(wǎng):263 ? ? ? ? ? ? ? ?
          秘書臺:269 ? ? ? ? ? ? ? ?
          青春熱線:64015039 ? ? ? ? ? ?
          人工信息服務(wù)臺:160 ? ? ? ? ? ? ? ?
          道路交通事故咨詢熱線:26688122 ? ? ? ? ? ?
          法律服務(wù)專線:1600148 ? ? ? ? ? ?
          老年癡呆癥咨詢熱線:8008208220 ? ? ? ? ?
          市政熱線:63088467 ? ? ? ? ? ?
          匪警:110 ? ? ? ? ? ? ? ?
          醫(yī)療急救臺:120 ? ? ? ? ? ? ? ?
          道路交通報(bào)警臺:122 ? ? ? ? ? ? ? ?
          緊急避孕熱線:62173454 ? ? ? ? ? ?
          移動電話服務(wù)臺:222 ? ? ? ? ? ? ? ?
          鐵路車票定票熱線:63217188 ? ? ? ? ? ?
          北京市熱力公司急修:65005943 ? ? ? ? ? ?
          天然氣急修:64269603 ? ? ? ? ? ?
          施工擾民投訴電話:68413817 ? 68017755 ?
          中國政法大學(xué)環(huán)境法研究和服務(wù)中心熱線電話:62228836 ? ? ? ? ? ?
          水上搜救專用電話:12395 ? ? ? ? ? ? ?
          天氣預(yù)報(bào)臺:12121 ? ? ? ? ? ? ?
          語音信箱:166 ? ? ? ? ? ? ? ?
          婦女熱線:64033383 ? 64073800 ?
          北京公共交通李素麗服務(wù)熱線:96166
          小公共汽車營運(yùn)服務(wù)監(jiān)督電話:68351150 ? 68351570 ?
          火車票新訂票熱線:51016666 ?51016688 ?
          復(fù)婚熱線:62383388 ? ? ? ? ? ?
          違規(guī)用水舉報(bào)電話:64247906 ? ? ? ? ? ?
          中華骨髓庫信息熱線:16895999 ? ? ? ? ? ?
          市地稅局舉報(bào)電話:12366
          免費(fèi)寵物熱線:160101011
          公共衛(wèi)生投訴電話:65066969
          拆遷舉報(bào)電話:64409883
          市公安局監(jiān)督養(yǎng)犬舉報(bào)電話:69738604
          道路質(zhì)量監(jiān)督電話:87501879
          勞保咨詢熱線:12333
          土地礦產(chǎn)法律免費(fèi)熱線:16829999
          單親孩子援助熱線:62356688
          熱水器搶修服務(wù)熱線:1600110
          市重大動物疫病指揮部辦公室:62015024 ? 62016809
          危改熱線:weigai@bjjs.gov.cn
          北京新聞廣播“新聞熱線”:8006101006
          民工維權(quán)熱線電話:12333
          西站24小時(shí)舉報(bào)電話:63984059
          燃?xì)鈭?bào)修熱線:96777
          自來水集團(tuán)報(bào)修中心:66189955
          電梯安全問題投訴電話:12365
          加油卡更換咨詢電話:64678605
          食品安全監(jiān)察處:82691421 ?12315
          黑車、黑導(dǎo)游舉報(bào)電話:96310
          北京通信公司北京客戶服務(wù)中心:10060
          北京通信公司話費(fèi)傳真號碼:65263399
          北京市電信公司客戶服務(wù)熱線:96388
          金銀建出租汽車調(diào)度中心:96103
          汽車援救電話:63489198
          駕駛員違章積分短信查詢熱線:9626899122
          城八區(qū)闖紅燈咨詢電話:9516888114
          北京西站問訊處:51826273
          北京南站問訊處:51837262
          北京北站問訊處:51866223
          鐵路信息查詢臺:962585
          火車票訂票熱線:962586
          客票中心訂票熱線:51827188
          北京火車站訂票熱線:51016666
          posted @ 2006-08-25 12:31 hopeshared 閱讀(419) | 評論 (0)編輯 收藏

          使用TreeViewer貢獻(xiàn)視圖(根據(jù)《Eclipse入門到精通》中的例子進(jìn)行的改編)


          作者:李紅霞 2005-8-13

          本文章允許轉(zhuǎn)載,但請要求注明文章作者及出處


          一 創(chuàng)建插件項(xiàng)目
          創(chuàng)建一個(gè)插件項(xiàng)目example.my.treeview,這個(gè)例子將向eclipse貢獻(xiàn)一個(gè)視圖,這個(gè)視圖采用樹(Treeviewer)來實(shí)現(xiàn)。

          下圖是本例的文件清單
          <抱歉,圖片傳不上來>
          + example.my.treeview
          + src
          ? + example.my.treeview
          ? ? - TreeviewPlugin.java
          ? + exampe.my.treeview.data
          ? ? - CityEntity.java
          ? ? - CountryEntity.java
          ? ? - DataFactory.java
          ? ? - PeopleEnrity.java
          ? + example.my.treeview.internal
          ? ? - ITreeEntry.java
          ? ? - TreeViewerContentProvider.java
          ? ? - TreeViewerLabelProvider.java
          ? ? - TreeViewPart.java
          ? + JRE System Library
          ? + Plug-in dependencies
          ? + META-INF
          ? ? - MENIFEST.MF
          ? - build.properties
          ? - plugin.xml

          二 準(zhǔn)備數(shù)據(jù)模型
          首先我們準(zhǔn)備數(shù)據(jù)模型,這些數(shù)據(jù)模型都保存在example.my.treeview.data這個(gè)包中

          我們定義一個(gè)接口ItreeEntry,這個(gè)接口將定義樹中每個(gè)節(jié)點(diǎn)共同特征(名稱和子節(jié)點(diǎn)),代碼如下

          package example.my.treeview.internal;
          import java.util.List;
          public interface ITreeEntry {
          ? ? ?public String getName();
          ? ? ?public void setName(String name);
          ? ? ?//設(shè)置得到子節(jié)點(diǎn)的集合
          ? ? ?public void setChildren(List children);
          ? ? ?public List getChildren();
          }

          這里涉及的實(shí)體一共有3個(gè),以下是他們的代碼

          package example.my.treeview.data;
          import java.util.List;
          import example.my.treeview.internal.ITreeEntry;
          public class CityEntity implements ITreeEntry{
          ? ? ?private Long id;//唯一識別碼
          ? ? ?private String name;//城市名
          ? ? ?private List peoples;//城市中的人
          ? ? ?public CityEntity(){}
          ? ? ?public CityEntity(String name){this.name=name;}
          ? ? ?public Long getId() {return id;}
          ? ? ?public void setId(Long id) {this.id = id;}
          ? ? ?public String getName() {return name;}
          ? ? ?public void setName(String name) {this.name = name;}
          ? ? ?public List getChildren() {return peoples;}
          ? ? ?public void setChildren(List peoples) {
          ? ? ? ? ? ?this.peoples = peoples;
          ? ? ?}
          }




          package example.my.treeview.data;
          import java.util.List;
          import example.my.treeview.internal.ITreeEntry;
          public class CountryEntity implements ITreeEntry{
          ? //唯一識別碼,在數(shù)據(jù)庫里常為自動遞增的ID列
          ? ? ?private Long id; ? ? ?
          private String name;//國家名
          //此國家所包含的城市的集合,集合元素為City對象
          ? ? ?private List cities; ? ? ?
          ? ? ?//兩個(gè)構(gòu)造函數(shù)
          ? ? ?public CountryEntity(){}
          ? ? ?public CountryEntity(String name){this.name = name;}
          ? //相應(yīng)的get和set方法
          ? ? ?public List getChildren() {return cities;}
          ? ? ?public void setChildren(List cities) {this.cities = cities;}
          ? ? ?public Long getId() {return id;}
          ? ? ?public void setId(Long id) {this.id = id;}
          ? ? ?public String getName() {return name;}
          ? ? ?public void setName(String name) {this.name = name;}
          }



          package example.my.treeview.data;
          import java.util.List;
          import example.my.treeview.internal.ITreeEntry;
          public class PeopleEntity implements ITreeEntry{
          ? ? ?private String name;
          ? ? ?public PeopleEntity(){}
          ? ? ?public PeopleEntity(String name){this.name=name;}
          ? ? ?public List getChildren(){return null;}
          ? ? ?public void setChildren(List children){}
          ? ? ?public String getName() {return name;}
          ? ? ?public void setName(String name) {this.name = name;}
          }


          三 創(chuàng)建樹中的數(shù)據(jù)結(jié)構(gòu)

          代碼如下

          package example.my.treeview.data;
          import java.util.ArrayList;
          public class DataFactory {
          ? ? ?public static Object createTreeData(){
          ? ? ? ? ? ?//生成人的數(shù)據(jù)對象
          ? ? ? ? ? ?PeopleEntity p1 = new PeopleEntity("李紅霞");
          ? ? ? ? ? ?PeopleEntity p2 = new PeopleEntity("金利軍");
          ? ? ? ? ? ?PeopleEntity p3 = new PeopleEntity("何濤");
          ? ? ? ? ? ?//生成城市的數(shù)據(jù)對象
          ? ? ? ? ? ?CityEntity city1=new CityEntity("湖北");
          ? ? ? ? ? ?CityEntity city2=new CityEntity("北京");
          ? ? ? ? ? ?CityEntity city3=new CityEntity("湖南");
          ? ? ? ? ? ?//生成國家的數(shù)據(jù)對象
          ? ? ? ? ? ?CountryEntity c1 = new CountryEntity("美國");
          ? ? ? ? ? ?CountryEntity c2 = new CountryEntity("中國");
          ? ? ? ? ? ?//將數(shù)據(jù)對象連接起來
          ? ? ? ? ? ?//人和城市的關(guān)系
          ? ? ? ? ? ?{
          ? ? ? ? ? ? ? ? ?ArrayList list = new ArrayList();
          ? ? ? ? ? ? ? ? ?list.add(p1);
          ? ? ? ? ? ? ? ? ?city1.setChildren(list);
          ? ? ? ? ? ?}
          ? ? ? ? ? ?{
          ? ? ? ? ? ? ? ? ?ArrayList list = new ArrayList();
          ? ? ? ? ? ? ? ? ?list.add(p2);
          ? ? ? ? ? ? ? ? ?city2.setChildren(list);
          ? ? ? ? ? ?}
          ? ? ? ? ? ?{
          ? ? ? ? ? ? ? ? ?ArrayList list = new ArrayList();
          ? ? ? ? ? ? ? ? ?list.add(p3);
          ? ? ? ? ? ? ? ? ?city3.setChildren(list);
          ? ? ? ? ? ?}
          ? ? ? ? ? ?//城市和國家的關(guān)系
          ? ? ? ? ? ?{
          ? ? ? ? ? ? ? ? ?ArrayList list = new ArrayList();
          ? ? ? ? ? ? ? ? ?list.add(city1);
          ? ? ? ? ? ? ? ? ?c1.setChildren(list);
          ? ? ? ? ? ?}
          ? ? ? ? ? ?{
          ? ? ? ? ? ? ? ? ?ArrayList list = new ArrayList();
          ? ? ? ? ? ? ? ? ?list.add(city2);
          ? ? ? ? ? ? ? ? ?list.add(city3);
          ? ? ? ? ? ? ? ? ?c2.setChildren(list);
          ? ? ? ? ? ?}
          ? ? ? ? ? ?//將國家置于一個(gè)對象之下,
          //這個(gè)對象可以是List也可以是數(shù)組
          ? ? ? ? ? ?{
          ? ? ? ? ? ? ? ? ?ArrayList list = new ArrayList();
          ? ? ? ? ? ? ? ? ?list.add(c1);
          ? ? ? ? ? ? ? ? ?list.add(c2);
          ? ? ? ? ? ? ? ? ?return list;
          ? ? ? ? ? ?}
          ? ? ?}
          }

          四 標(biāo)簽器和內(nèi)容器
          TreeViewer和TableViewer一樣,是用內(nèi)容器和標(biāo)簽器來控制記錄對象的顯示,并且使用內(nèi)容器和標(biāo)簽器的語句也是一樣的。

          下面是標(biāo)簽器的代碼

          package example.my.treeview.internal;
          import org.eclipse.jface.viewers.ILabelProvider;
          import org.eclipse.jface.viewers.ILabelProviderListener;
          import org.eclipse.swt.graphics.Image;
          /**
          * @author hopeshared
          * 標(biāo)簽提供器,控制紀(jì)錄在樹中顯示的文字和圖像等
          */
          public class TreeViewerLabelProvider
          implements ILabelProvider{
          ? ? ?//紀(jì)錄顯示 的文字,不能返回null
          ? ? ?public String getText(Object element){
          ? ? ? ? ? ?ITreeEntry entry = (ITreeEntry)element;
          ? ? ? ? ? ?return entry.getName();
          ? ? ?}
          ? ? ?//紀(jì)錄顯示的圖像
          ? ? ?public Image getImage(Object element){
          ? ? ? ? ? ?return null;
          ? ? ?}
          ? ? ?//以下方法暫不用,空實(shí)現(xiàn)
          ? ? ?public void addListener(ILabelProviderListener listener){}
          ? ? ?public void dispose(){}
          ? ? ?public boolean isLabelProperty(Object e, String p){return false;}
          ? ? ?public void removeListener(ILabelProviderListener listen){}
          }


          下面是內(nèi)容器的代碼

          package example.my.treeview.internal;
          import java.util.List;
          import org.eclipse.jface.viewers.ITreeContentProvider;
          import org.eclipse.jface.viewers.Viewer;
          /**
          * @author hopeshared
          * 內(nèi)容器,由它決定哪些對象應(yīng)該輸出在TreeViewer里顯示
          */
          public class TreeViewerContentProvider
          implements ITreeContentProvider{
          ? ? ?//由這種方法決定樹的哪一級顯示哪些對象
          ? ? ?public Object[] getElements(Object inputElement)
          ? ? ?{
          ? ? ? ? ? ?if(inputElement instanceof List){
          ? ? ? ? ? ? ? ? ?List list = (List)inputElement;
          ? ? ? ? ? ? ? ? ?return list.toArray();
          ? ? ? ? ? ?}else{
          ? ? ? ? ? ? ? ? ?return new Object[0];//生成一個(gè)空的數(shù)組
          ? ? ? ? ? ?}
          ? ? ?}
          ? ? ?//判斷某節(jié)點(diǎn)是否有子節(jié)點(diǎn),如果有子節(jié)點(diǎn),
          //這時(shí)節(jié)點(diǎn)前都有一個(gè)“+”號圖標(biāo)
          ? ? ?public boolean hasChildren(Object element){
          ? ? ? ? ? ?ITreeEntry entry = (ITreeEntry)element;
          ? ? ? ? ? ?List list = entry.getChildren();
          ? ? ? ? ? ?if(list==null||list.isEmpty()){return false;
          ? ? ? ? ? ?}else{return true;}
          ? ? ?}
          ? ? ?//由這個(gè)方法來決定父節(jié)點(diǎn)應(yīng)該顯示哪些子節(jié)點(diǎn)
          ? ? ?public Object[] getChildren(Object parentElement){
          ? ? ? ? ? ?ITreeEntry entry = (ITreeEntry)parentElement;
          ? ? ? ? ? ?List list = entry.getChildren();
          ? ? ? ? ? ?if(list==null || list.isEmpty()){return new Object[0];
          ? ? ? ? ? ?}else{return list.toArray();} ? ? ? ? ? ?
          ? ? ?}
          ? ? ?//以下方法空實(shí)現(xiàn)
          ? ? ?public Object getParent(Object element){return null;}
          ? ? ?public void dispose(){}
          ? ? ?public void inputChanged(Viewer v, Object oldInput, Object newInput){}
          }

          五 修改清單文件
          下面給出的是plugin.xml文件代碼

          <?xml version="1.0" encoding="UTF-8"?>
          <?eclipse version="3.0"?>
          <plugin>
          ? <extension point="org.eclipse.ui.views">
          ? ? <view
          ? ? class="example.my.treeview.internal.TreeViewPart"
          id="example.my.treeview.treeview"
          name="my first tree view plugin"/>
          ? </extension>
          </plugin>

          六 插件的實(shí)現(xiàn)
          在清單文件中已經(jīng)指出了這個(gè)視圖的實(shí)現(xiàn)類是example.my.treeview.internal.TreeViewPart,下面給出這個(gè)文件的代碼

          package example.my.treeview.internal;
          import org.eclipse.jface.viewers.TreeViewer;
          import org.eclipse.swt.SWT;
          import org.eclipse.swt.layout.FillLayout;
          import org.eclipse.swt.widgets.Composite;
          import org.eclipse.ui.part.ViewPart;
          import example.my.treeview.data.DataFactory;
          public class TreeViewPart extends ViewPart{
          ? ? ?public void createPartControl(Composite parent){
          ? ? ? ? ? ?Composite topComp = new Composite(parent, SWT.NONE);
          ? ? ? ? ? ?topComp.setLayout(new FillLayout());
          ? ? ? ? ? ?TreeViewer tv = new TreeViewer(topComp, SWT.BORDER);
          ? ? ? ? ? ?tv.setContentProvider(new TreeViewerContentProvider());
          ? ? ? ? ? ?tv.setLabelProvider(new TreeViewerLabelProvider());
          ? ? ? ? ? ?Object inputObj = DataFactory.createTreeData();
          ? ? ? ? ? ?tv.setInput(inputObj);
          ? ? ?}
          ? ? ?public void setFocus(){}
          }

          七 運(yùn)行結(jié)果
          <抱歉,圖片上傳失敗>


          八 給節(jié)點(diǎn)增加動作
          增加一個(gè)ActionGroup類

          package example.my.treeview.internal;
          import org.eclipse.jface.action.Action;
          import org.eclipse.jface.action.IMenuManager;
          import org.eclipse.jface.action.MenuManager;
          import org.eclipse.jface.dialogs.MessageDialog;
          import org.eclipse.jface.viewers.IStructuredSelection;
          import org.eclipse.jface.viewers.TreeViewer;
          import org.eclipse.swt.widgets.Menu;
          import org.eclipse.swt.widgets.Tree;
          import org.eclipse.ui.actions.ActionGroup;
          /**
          * @author hopeshared
          * 生成菜單Menu,并將兩個(gè)Action傳入
          */
          public class MyActionGroup extends ActionGroup{
          ? ? ?private TreeViewer tv;
          ? ? ?public MyActionGroup(TreeViewer treeViewer){
          ? ? ? ? ? ?this.tv = treeViewer;
          ? ? ?}
          ? ? ?//生成菜單Menu,并將兩個(gè)Action傳入
          ? ? ?public void fillContextMenu(IMenuManager mgr){
          ? ? ? ? ? ?//加入兩個(gè)Action對象到菜單管理器
          ? ? ? ? ? ?MenuManager menuManager = (MenuManager)mgr;
          ? ? ? ? ? ?menuManager.add(new OpenAction());
          ? ? ? ? ? ?menuManager.add(new RefreshAction());
          ? ? ? ? ? ?//生成Menu并掛在樹Tree上
          ? ? ? ? ? ?Tree tree = tv.getTree();
          ? ? ? ? ? ?Menu menu = menuManager.createContextMenu(tree);
          ? ? ? ? ? ?tree.setMenu(menu);
          ? ? ?}
          ? ? ?//打開Action類
          ? ? ?private class OpenAction extends Action{
          ? ? ? ? ? ?public OpenAction(){
          ? ? ? ? ? ? ? ? ?setText("打開");
          ? ? ? ? ? ?}
          ? ? ? ? ? ?//繼承自Action的方法,動作代碼寫在此方法中
          ? ? ? ? ? ?public void run(){
          ? ? ? ? ? ? ? ? ?IStructuredSelection selection = (IStructuredSelection)tv.getSelection();
          ? ? ? ? ? ? ? ? ?ITreeEntry obj = (ITreeEntry)(selection.getFirstElement());
          ? ? ? ? ? ? ? ? ?if(obj != null){
          ? ? ? ? ? ? ? ? ? ? ? ?MessageDialog.openInformation(null, null, obj.getName());
          ? ? ? ? ? ? ? ? ?}
          ? ? ? ? ? ?}
          ? ? ?}
          ? ? ?//刷新的Action類
          ? ? ?private class RefreshAction extends Action{
          ? ? ? ? ? ?public RefreshAction(){
          ? ? ? ? ? ? ? ? ?setText("刷新");
          ? ? ? ? ? ?}
          ? ? ? ? ? ?//繼承自Action的方法,動作代碼寫在此方法中
          ? ? ? ? ? ?public void run(){
          ? ? ? ? ? ? ? ? ?tv.refresh();
          ? ? ? ? ? ?}
          ? ? ?}
          }

          接著,修改TreeViewPart.java,代碼如下

          ……
          Object inputObj = DataFactory.createTreeData();
          ? ? ? ? ? ?//-------------加入動作開始
          ? ? ? ? ? ?MyActionGroup actionGroup = new MyActionGroup(tv);
          ? ? ? ? ? ?actionGroup.fillContextMenu(new MenuManager());
          ? ? ? ? ? ?//-------------加入動作結(jié)束
          ? ? ? ? ? ?tv.setInput(inputObj);
          ……


          結(jié)果如下圖所示
          <抱歉,圖片上傳不成功>


          九 自定義擴(kuò)展點(diǎn)
          我們想將這個(gè)視圖的顯示內(nèi)容與視圖框架分開,這樣,我們需要修改視圖顯示內(nèi)容的時(shí)候只要重新貢獻(xiàn)一次顯示內(nèi)容就可以了。
          9.1 添加shema文件
          這個(gè)sheme文件是采用可視化編輯器進(jìn)行編輯,然后pde自動生成的,代碼如下

          <?xml version='1.0' encoding='UTF-8'?>
          <!-- Schema file written by PDE -->
          <schema targetNamespace="example.my.treeview">
          <annotation>
          ? ? <appInfo>
          ? ? ? <meta.schema plugin="example.my.treeview" id="datafactory" name="Data Factory"/>
          ? ? </appInfo>
          ? ? <documentation>
          ? ? ? [Enter description of this extension point.]
          ? ? </documentation>
          ? </annotation>
          <element name="extension">
          ? ? <complexType>
          ? ? ? <sequence><element ref="factory"/></sequence>
          ? ? ? <attribute name="point" type="string" use="required">
          ? ? ? ? <annotation><documentation></documentation></annotation></attribute>
          ? ? ? <attribute name="id" type="string">
          ? ? ? ? <annotation><documentation></documentation></annotation></attribute>
          ? ? ? <attribute name="name" type="string">
          ? ? ? ? <annotation><documentation></documentation>
          ? ? ? ? ? <appInfo><meta.attribute translatable="true"/></appInfo></annotation>
          ? ? ? </attribute>
          ? ? </complexType>
          ? </element>
          ? <element name="factory">
          ? ? <complexType>
          ? ? ? <attribute name="id" type="string">
          ? ? ? ? <annotation><documentation></documentation></annotation></attribute>
          ? ? ? <attribute name="name" type="string">
          ? ? ? ? <annotation><documentation></documentation></annotation></attribute>
          ? ? ? <attribute name="class" type="string" use="required">
          ? ? ? ? <annotation><documentation></documentation></annotation></attribute>
          ? ? </complexType>
          ? </element>
          ? <annotation>
          ? ? <appInfo><meta.section type="since"/></appInfo>
          <documentation>[Enter the first release in which this extension point appears.]
          </documentation>
          ? </annotation>
          ? <annotation>
          ? ? <appInfo><meta.section type="examples"/></appInfo>
          ? ? <documentation>[Enter extension point usage example here.]</documentation>
          ? </annotation>
          ? <annotation>
          ? ? <appInfo><meta.section type="apiInfo"/></appInfo>
          ? ? <documentation>[Enter API information here.]</documentation></annotation>
          ? <annotation>
          ? ? <appInfo><meta.section type="implementation"/></appInfo>
          <documentation>
          [Enter information about supplied implementation of this extension point.]
          ? ? </documentation></annotation>
          ? <annotation>
          ? ? <appInfo><meta.section type="copyright"/></appInfo>
          ? ? <documentation></documentation></annotation>
          </schema>

          9.2 創(chuàng)建接口文件
          ItreeEntry.java之前就已經(jīng)創(chuàng)建好了,不需要修改。現(xiàn)在添加另一個(gè)接口文件,代碼如下:

          package example.my.treeview.internal;
          public interface IDataFactory {
          ? ? ?public Object createTreeData();
          }


          于是我們修改DataFactory.java,使它實(shí)現(xiàn)這個(gè)接口。
          9.3 修改清單文件
          我們來修改清單文件,加入擴(kuò)展點(diǎn)聲明,并擴(kuò)展它,代碼如下

          ……
          <extension-point id="datafactory" name="Data Factory"
          schema="schema/datafactory.exsd"/>
          <extension point="example.my.treeview.datafactory">
          <factoryclass="example.my.treeview.data.DataFactory"/>
          </extension>
          ……


          9.4 修改TreeviewPlugin.java
          增加一個(gè)方法Object loadDataFactory(),代碼如下

          ……
          public static Object loadDataFactory(){
          ? ? ? ?IPluginRegistry r=Platform. getPluginRegistry();
          ? ? ? ?String pluginID="example.my.treeview";
          ? ? ? ?String extensionPointID="datafactory";
          ? ? ? ?IExtensionPoint p=r.getExtensionPoint( pluginID, extensionPointID);
          ? ? ? ?IConfigurationElement[] c=p.getConfigurationElements();
          ? ? ? ?if( c != null) {
          ? ? ? ? ? ? ?for( int i= 0; i <c.length; i++) {
          ? ? ? ? ? ? ? ? ? ?IDataFactory data = null;
          ? ? ? ? ? ? ? ? ? ?try { data=( IDataFactory)c
          .createExecutableExtension("class");
          ? ? ? ? ? ? ? ? ? ? ? ? ?if( data != null){ return data.createTreeData(); }
          ? ? ? ? ? ? ? ? ? ?} catch( CoreException x) { }}}
          ? ? ? ?return new Object();
          ? }
          ……

          9.5 修改TreeViewPart.java

          Object inputObj = DataFactory.createTreeData();
          替換為
          Object inputObj = TreeviewPlugin.loadDataFactory();

          9.6 其他輔助文件
          其實(shí)TreeViewerLabelProvider.java和TreeViewerContentProvider.java可以看成是對DataFactory這個(gè)擴(kuò)展點(diǎn)的輔助文件

          9.7運(yùn)行
          跟之前的實(shí)現(xiàn)沒有區(qū)別,但是我們向eclipse貢獻(xiàn)了一個(gè)擴(kuò)展點(diǎn)


          十 參考資料
          《Eclipse入門到精通》
          www.sohozu.com 《自己動手編寫Eclipse擴(kuò)展點(diǎn)》
          EclipseCon2005_Tutorial1.pdf 《Contributing to Eclipse: Understanding and WritingPlug- ins》


          圖片:
          ?

          圖片:
          ?


          經(jīng)過一個(gè)多小時(shí)的努力。。。(嘿嘿,以前沒有仔細(xì)研究Property什么的,今天弄了一下)

          終于出現(xiàn)了property并且可以修改屬性頁中的值




          代碼

          example.my.treeview.rar


          哦,補(bǔ)充一下,由于模型(就是treeviewer中的初始數(shù)據(jù))是寫死的,改的property其實(shí)是修改了內(nèi)存中的對象的值。假如用emf做模型持久化,就會保存修改。但是目前是不能保存修改的。


          關(guān)于本文的討論還是很多的,也有很多有用的信息。見http://www.eclipseworld.org/bbs/read.php?tid=168
          本文第一次發(fā)表是在社區(qū)之中,本來也沒覺得有轉(zhuǎn)到blog的必要,但是后來發(fā)覺自己的記憶力越來越差,曾經(jīng)作過的都忘記的差不多了,為了避免丟失,還是存在這里備份比較好。
          posted @ 2006-07-25 13:54 hopeshared 閱讀(3524) | 評論 (1)編輯 收藏

          總是寫不好ppt,為什么呢?
          先把ppt的寫法總結(jié)放在這里,這樣就不容易忘記了。

          1. 選擇合適的模板,通常選擇根內(nèi)容相關(guān),簡單清新的模板就可以了。當(dāng)然,也要看ppt是用來做什么的。
          2. 標(biāo)題簡單明了,突出核心內(nèi)容。
          3. 第一頁一般為Outline或者Agenda。我經(jīng)常犯的錯(cuò)誤是第一頁命名為Outline,但是Outline其實(shí)跟Introduction是一個(gè)抽象級別的。
          4. 每頁的Items都要在一個(gè)抽象級別。
          5. 每個(gè)子Item都要從同一個(gè)角度來劃分
          6. 通常在Introduction中介紹Challeges。如果Challeges不太多Solutions也不復(fù)雜,那么可以將兩者合并作為一個(gè)Topic。如果Challeges太多在Introduction中講不清楚,那么可以在Introduction之后列一個(gè)Challeges的Topic。
          7. Introduction中應(yīng)列出問題,現(xiàn)狀,目前的挑戰(zhàn)以及High Level的解決辦法。
          8. ppt的一般結(jié)構(gòu)是:本項(xiàng)目的意義,難度,如何解決,演示。
          9. Introduction之后應(yīng)該緊接著介紹項(xiàng)目中“創(chuàng)造”的概念。
          10. Solution應(yīng)該是緊接在Challeges后面的一個(gè)Topic,它仍然是抽象的描述解決方法。更具體的涉及到技術(shù)細(xì)節(jié)的應(yīng)歸結(jié)為Approach或者Technics緊跟在Solution之后作為補(bǔ)充。
          11. 實(shí)現(xiàn)本系統(tǒng)用到了其他的成熟技術(shù)。那么應(yīng)該首先說明遇到了什么問題(why),如何來解決(how),有多少種解決方法(what),為什么選擇你使用的這種(why)。我想可能要補(bǔ)充上如何來用它吧。
          12. 具體的技術(shù)細(xì)節(jié)應(yīng)該是在Scenarios之前。
          13. Scenarios應(yīng)該用少量的文字配合大量的圖片來表達(dá),不應(yīng)該出現(xiàn)技術(shù)
          14. 項(xiàng)目的關(guān)鍵特性要結(jié)合Demo體現(xiàn)出來
          15. ppt中的結(jié)構(gòu)圖應(yīng)該采用立體感強(qiáng)的圖片來表示。ppt中出現(xiàn)的圖片都應(yīng)該有很強(qiáng)的表現(xiàn)力(千言萬語盡在圖中)。
          16. 作為ppt還有一點(diǎn)跟paper不一樣,那就是,不再需要Reference。而Conclusion&Future work則應(yīng)該提煉成精簡的Sumerize。

          最后,ppt的靈魂就是邏輯,邏輯,還是邏輯。一定要有邏輯。

          經(jīng)常作總結(jié),是增強(qiáng)邏輯性,條理性的最有效途徑。

          sigh,誰讓我一向不用邏輯思考問題呢,555

          posted @ 2006-07-21 14:06 hopeshared 閱讀(8843) | 評論 (10)編輯 收藏

          作者:Brian McBride
          發(fā)表時(shí)間:2000年9月2日
          原文鏈接: http://www.hpl.hp.co.uk/people/bwm/rdf/jena/rssinjena.htm
          譯者:dlee
          翻譯時(shí)間:2001年5月26日

          ? ? RSS 1.0 是最近宣布的一個(gè)格式,順從于 W3C 的 RDF (資源定義框架),用來分發(fā)(distributing) 站點(diǎn)摘要 (site summary) 和企業(yè)聯(lián)合 (syndication) 元數(shù)據(jù)。一個(gè)站點(diǎn)摘要文檔的例子可以在規(guī)范中找到。Jena 是一套實(shí)驗(yàn)性的用來處理 RDF 的 Java API。這篇筆記描述了一個(gè)應(yīng)用程序使用 Jena 來將一個(gè)站點(diǎn)摘要文檔翻譯成 HTML。整個(gè)程序的源代碼作為 RenderToHTML 可以在 Jena 發(fā)布的例子包里得到。

          ? ? 這篇文章和例子代碼基于 RSS 規(guī)范候選發(fā)布版本1 (Release Candidate 1 version)。
          ? ? 這個(gè)應(yīng)用程序以創(chuàng)建一個(gè) RDF 模型開始,實(shí)際上在內(nèi)存中是一個(gè) RDF statement 的集合。然后解析站點(diǎn)摘要文檔,使用一個(gè) RDF 解析器,并加載 statement 到新創(chuàng)建的模型中。

          ? ? ? Model model = new ModelMem();
          ? ? ? model.read(" http://www.xml.com/xml/news.rss");

          ? ? 在寫出一個(gè)樣板 HTML 頭后,程序列出和處理在輸入流中的每個(gè) channel。在 RDF 術(shù)語中,channel 是具有一個(gè) rdf:type 屬性的 rss:channel 的資源。我們使用 Jena API 來列出具有一個(gè)有這個(gè)值的 rdf:type 屬性的所有的資源。在下面的代碼中,假設(shè)輸出是一個(gè)接收 HTML 輸出的 PrintWriter。

          ? ? ? ResIterator channels =? model.listSubjectsWithProperty(RDF.type, RSS.channel);
          ? ? ? while (channels.hasNext()) {
          ? ? ? ? ? renderChannel(channels.next(), out);
          ? ? ? }

          ? ? 為了呈現(xiàn) (render) 一個(gè) channel,程序首先寫出它的 title,description 和相關(guān)的 image 和 textinput 字段 (如果有的話)。getProperty 方法用來得到 channel 的 title,link 和 description 屬性,隨后這些可以被呈現(xiàn)為 HTML。

          ? ? ? void renderChannel(Resource channel, PrintStream out)
          ? ? ? ? ? ? ?throws RDFException {
          ? ? ? ? ? String url = null;
          ? ? ? ? ? String title = null;
          ? ? ? ? ? String desc = null;

          ? ? ? ? ? url = channel.getProperty(RSS.link).getString();
          ? ? ? ? ? title = channel.getProperty(RSS.title).getString();
          ? ? ? ? ? desc = channel.getProperty(RSS.description).getString();

          ? ? 一個(gè) channel 可以有一個(gè)相關(guān)聯(lián)的 image 和 textinput,測試是否存在這些屬性和是否需要調(diào)用合適的方法來呈現(xiàn)它們是很簡單的。

          ? ? ? if (channel.hasProperty(RSS.image)) {
          ????? ? ? renderImage(channel.getProperty(RSS.image) .getResource(), out);
          ????? }
          ????? if (channel.hasProperty(RSS.textinput)) {
          ????? ? ? renderImage(channel.getProperty(RSS.textinput) .getResource(), out);
          ????? }

          ? ? 為了處理一個(gè) image,同樣的調(diào)用被用來確定 image 的屬性。

          ????? String url = null;
          ????? String title = null;

          ????? // does the image have a link?
          ????? if (image.hasProperty(RSS.link)) {
          ????? ??? url = image.getProperty(RSS.link).getString();
          ????? }

          ????? // does the image have a title?
          ????? if (image.hasProperty(RSS.title)) {
          ????????? title = image.getProperty(RSS.title).getString();
          ????? } image.getProperty(SSF.title).getString();

          ? ? 然后這個(gè) image 可以被呈現(xiàn)成為 output stream。textinput 以 相似的方法處理。

          ? ? channel 有一個(gè) items 屬性,它的值為一個(gè) RDF sequence。因此使用 getProperty 方法得到這個(gè) sequence 就很簡單的了。然后迭代每一個(gè)元素以呈現(xiàn)它。

          ????? if (channel.hasProperty(RSS.items)) {
          ????? ??? Seq items = channel.getProperty(RSS.items).getSeq();
          ????? ??? for (int i=1; i<= items.size(); i++) {
          ????? ??? ? ? renderItem(items.getResource(i), out);
          ????? ??? }
          ????? }

          ? ? 以相同的模式呈現(xiàn)每一個(gè) items。首先得到需要呈現(xiàn)的 items 的屬性,然后寫出 HTML。

          ????? void renderItem(Resource item, PrintWriter out) {
          ????? ??? String url = item.getProperty(RSS.link).getString();
          ????? ??? String title = item.getProperty(RSS.title).getString();
          ????? ??? String desc = item.getProperty(RSS.description) .getString();
          ????? ??? ...
          ????? }

          ? ? 使用 Jena 來處理 RSS 1.0 流是簡單和直接的。

          ? ? Brian McBride
          ? ? HP實(shí)驗(yàn)室,2000年9月2日
          ? ? 修改于2000年12月2日
          posted @ 2006-07-20 10:36 hopeshared 閱讀(631) | 評論 (0)編輯 收藏

          僅列出標(biāo)題
          共30頁: First 上一頁 5 6 7 8 9 10 11 12 13 下一頁 Last 
          主站蜘蛛池模板: 象州县| 姚安县| 皋兰县| 岳西县| 沁源县| 阿勒泰市| 丹棱县| 临泉县| 开阳县| 红桥区| 庆元县| 日喀则市| 鄂托克旗| 济阳县| 永福县| 习水县| 鹤山市| 麻江县| 南岸区| 永仁县| 双牌县| 安乡县| 双鸭山市| 白山市| 商南县| 休宁县| 芷江| 资源县| 西乌珠穆沁旗| 那坡县| 承德县| 安顺市| 珲春市| 昂仁县| 库伦旗| 英德市| 玛多县| 汪清县| 扎鲁特旗| 新野县| 灵山县|