学习Tuscany
安装Tuscany的Eclipse插件
- 首先,启动Eclipse,并依次点击菜单:Help -> Software Updates -> Find and Install,选择“Search for new features to install”,点击下一步:
- 在接下来的对话框中,点击“New Remote Site…”创建一个新的站点,命名为“Tuscany”,其地址为:http://people.apache.org/~jsdelfino/tuscany/tools/updatesite/
- 确认选择了我们刚刚新增的一个远程站点,并点击“Finish”按钮
- 选择“Apache Tuscany SCA Tools”,并在接下来的窗口一路点击Next,直到点击Finish为止,接受该插件的使用协议(Plugin License)
该应用是由四个服务组成的,这个应用是一个在线商店,这里有一个目录服务,你可以通过它取得项目名单,依靠currencyCode属性来判断是以美元还是欧元提供项目价格,目录服务本身不去做货币换算的工作,相反它引用了一个CurrencyConverter服务去完成这个工作。接下来,这里还有一个ShoppingCart服务,从目录选择了的项目可以被加进去(购物车),它是使用REST实现的;Catalog使用的是一个JSONRPC绑定,ShoppingCart呢则是通过ATOM进行绑定,最后,就是提供给用户的、基于浏览器的界面服务的Store组件了,Store服务组件分别通过JSONRPC和ATOM绑定使用Catalog和ShoppingCart服务。
创建一个Java工程
这一步你要在Eclipse中建立一个Java工程,点击工具栏上的New Java Project按钮 来打开新建工程的对话框,接下来输入store作为工程名称,并选择Create separate
folders for sources and class files:
点击下一步按钮,在接下来的窗口打开Libraries选项卡,点击Add Library...按钮以添加Tuscany Libraray到工程中:
最后,点击Finish按钮结束工程创建。
构建服务
首先,创建两个包目录,以便在接下来的步骤中存放服务的实现。选择“store”工程,点击工具栏上的新建Java包按钮 启动创建包对话框。接下来,输入services作为包名,点击Finish按钮关闭对话框。
记下来,会在services包内放入普通的服务,ufservices内是界面相关服务。
Catalog
现在,准备创建Catalog服务的接口和实现。
选择“services”包,接下来在工具栏的下拉菜单中点击“New Java Class” 按钮 和“New Java Interface”按钮 ,在弹出的对话框中以“Catalog”作为接口名,并点击Finish关闭对话框,这时在Java编辑器中就会打开新增的Java接口,将下面这段Java接口代码Copy-Paste到编辑器内:
import org.osoa.sca.annotations.Remotable;
@Remotable
public interface Catalog {
String[] get();
}
再次选中“services”包,点击“New Java Class”按钮 ,在弹出的对话框中以“CatalogImpl”作为类的名字,将“Catalog”作为该类的实现接口,点击Finish完成。
在Java编辑器中会打开我们新增的类,将下面的代码复制过去:
import java.util.ArrayList;
import java.util.List;
import org.osoa.sca.annotations.Init;
import org.osoa.sca.annotations.Property;
import org.osoa.sca.annotations.Reference;
public class CatalogImpl implements Catalog {
@Property
public String currencyCode = " USD " ;
@Reference
public CurrencyConverter currencyConverter;
private List < String > catalog = new ArrayList < String > ();
@Init
public void init() {
String currencySymbol = currencyConverter.getCurrencySymbol(currencyCode);
catalog.add( " Apple - " + currencySymbol +
currencyConverter.getConversion( " USD " , currencyCode, 2.99f ));
catalog.add( " Orange - " + currencySymbol +
currencyConverter.getConversion( " USD " , currencyCode, 3.55f ));
catalog.add( " Pear - " + currencySymbol +
currencyConverter.getConversion( " USD " , currencyCode, 1.55f ));
}
public String[] get() {
String[] catalogArray = new String[catalog.size()];
catalog.toArray(catalogArray);
return catalogArray;
}
}
在这一步,我们将创建CurrencyConverter的接口和实现,首先,按照之前的方式建立接口和类文件,并将下面的代码复制过去:
import org.osoa.sca.annotations.Remotable;
@Remotable
public interface CurrencyConverter {
public float getConversion(String fromCurrenycCode,
String toCurrencyCode, float amount);
public String getCurrencySymbol(String currencyCode);
}
public class CurrencyConverterImpl implements CurrencyConverter {
public float getConversion(String fromCurrencyCode,
String toCurrencyCode, float amount) {
if (toCurrencyCode.equals( " USD " ))
return amount;
else if (toCurrencyCode.equals( " EUR " ))
return amount * 0.7256f ;
return 0 ;
}
public String getCurrencySymbol(String currencyCode) {
if (currencyCode.equals( " USD " ))
return " $ " ;
else
if (currencyCode.equals( " EUR " ))
return " ? " ;
return " ? " ;
}
}
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.tuscany.sca.binding.feed.collection.Collection;
import org.apache.tuscany.sca.binding.feed.collection.NotFoundException;
import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link;
public class ShoppingCartImpl implements Collection {
// needs to change to instance var once conversation scope works
private static Map < String, Entry > cart = new HashMap < String, Entry > ();
public Feed getFeed() {
Feed feed = new Feed();
feed.setTitle( " shopping cart " );
Content subtitle = new Content();
subtitle.setValue( " Total : " + getTotal());
feed.setSubtitle(subtitle);
feed.getEntries().addAll(cart.values());
return feed;
}
public Entry get(String id) throws NotFoundException {
return cart.get(id);
}
public Entry post(Entry entry) {
String id = " cart- " + UUID.randomUUID().toString();
entry.setId(id);
Link link = new Link();
link.setRel( " edit " );
link.setHref( "" + id);
entry.getOtherLinks().add(link);
link = new Link();
link.setRel( " alternate " );
link.setHref( "" + id);
entry.getAlternateLinks().add(link);
entry.setCreated( new Date());
cart.put(id, entry);
return entry;
}
public void put(String id, Entry entry) throws NotFoundException {
entry.setUpdated( new Date());
cart.put(id, entry);
}
public void delete(String id) throws NotFoundException {
if (id.equals( "" ))
cart.clear();
else
cart.remove(id);
} private String getTotal() {
float total = 0 ;
String symbol = "" ;
if ( ! cart.isEmpty()) {
Entry entry = cart.values().iterator().next();
String item = ((Content)entry.getContents().get( 0 )).getValue();
symbol = item.substring(item.indexOf( " - " ) + 2 , item.indexOf( " - " ) + 3 );
}
for (Entry entry : cart.values()) {
String item = ((Content)entry.getContents().get( 0 )).getValue();
total += Float.valueOf(item.substring(item.indexOf( " - " ) + 3 ));
}
return symbol + String.valueOf(total);
}
}
< head >
< title > Store </ TITLE >
< script type ="text/javascript" src ="store.js" ></ script >
< script language ="JavaScript" >
// Reference
catalog = ( new JSONRpcClient( " ../Catalog " )).Catalog;
// Reference
shoppingCart = new AtomClient( " ../ShoppingCart " );
function catalog_getResponse(items) {
var catalog = "" ;
for ( var i = 0 ; i < items.length; i ++ )
catalog += ' <input name="items" type="checkbox" value=" ' +
items[i] + ' "> ' + items[i] + ' <br> ' ;
document.getElementById( ' catalog ' ).innerHTML = catalog;
}
function shoppingCart_getResponse(feed) {
if (feed != null ) {
var entries = feed.getElementsByTagName( " entry " );
var list = "" ;
for ( var i = 0 ; i < entries.length; i ++ ) {
var item = entries[i].getElementsByTagName( " content " )[ 0 ].firstChild.nodeValue;
list += item + ' <br> ' ;
}
document.getElementById( " shoppingCart " ).innerHTML = list;
document.getElementById( ' total ' ).innerHTML = feed.getElementsByTagName( " subtitle " )[ 0 ].firstChild.nodeValue;
}
}
function shoppingCart_postResponse(entry) {
shoppingCart.get( "" , shoppingCart_getResponse);
}
function addToCart() {
var items = document.catalogForm.items;
var j = 0 ;
for ( var i = 0 ; i < items.length; i ++ )
if (items[i].checked) {
var entry = ' <entry xmlns="http://www.w3.org/2005/Atom"><title>cart-item</title><content type="text"> ' + items[i].value + ' </content></entry> '
shoppingCart.post(entry, shoppingCart_postResponse);
items[i].checked = false ;
}
}
function checkoutCart() {
document.getElementById( ' store ' ).innerHTML = ' <h2> ' +
' Thanks for Shopping With Us!</h2> ' +
' <h2>Your Order</h2> ' +
' <form name="orderForm" action="store.html"> ' +
document.getElementById( ' shoppingCart ' ).innerHTML +
' <br> ' +
document.getElementById( ' total ' ).innerHTML +
' <br> ' +
' <br> ' +
' <input type="submit" value="Continue Shopping"> ' +
' </form> ' ;
shoppingCart.del( "" , null );
}
function deleteCart() {
shoppingCart.del( "" , null );
document.getElementById( '