使用Eclipse构建Tuscany实例

前言:

       这个例子只是一个简单的HelloWord的例子。翻译是转载的。 写于2011-11-05

官网示例:

       http://tuscany.apache.org/getting-started-with-tuscany-using-tuscany-eclipse-plugin.html

原文内容:

准备、设置、开始——开始使用Tuscany

这篇文章将向你描述如何下载Tuscany,在Eclipse中将Tuscany添加到用户库中,创建一个名为Store的Java工程实例,然后运行它并通过浏览器访问它。

 虽然本指南的很多图片是基于Java SCA 1.3.2版本的,但是你在操作那些必要的步骤是还是应该尽量使用最新版本。

“点击此处,获取本指南视频”

安装Tuscany

你需要做的第一件事情是为你将要下载的Tuscany介质创建一个存放文件夹。

接下来,你下载最新版本的介质。登陆浏览器,输入下面网址: 

最新版本 - http://cwiki.apache.org/TUSCANY/sca-java-releases.html

注意:上面地址在我访问不到,可使用:http://archive.apache.org/dist/tuscany/java/sca/

将bin文件压缩包和src文件压缩包都下载到你刚创建的文件夹中,下载后,你在文件夹中将看到以下内容:

然后,解压bin文件夹压缩包到本地,解压完成后,你将在你的硬盘上看到如下目录结构:

在Eclipse中配置Tuscany

启动Eclipse并创建一个包含Tuscany运行所必须的所有jar包的用户库。

从菜单栏中选择Window 然后Preferences...打开参数对话框。
在对话框左侧的导航树中点击Java ,再点击Build Path,然后点击User Libraries 
点击用户库对话框的右侧的New...按钮创建一个新的用户库Tuscany。

刚创建的用户库是空的,你需要通过点击右侧的Add JARs...按钮将Tuscany安装目录下的lib子目录中的所有jar包导入到新建的Tuscany用户库中。

 

你可能对调试Tuscany源码有兴趣,下一步我们将把Tuscany源码包和运行jar包相匹配。在用户库对话框中,下拉滚动条,直到你找到tuscany运行jar包,选择Source attachment

 

点击Edit... 右侧的编辑按钮,在弹出编辑对话框中点击External File...按钮,然后选中你之前下载的Tuscany的源码包。

 

通过点击OK 按钮,关闭本对话框和参数对话框,完成Eclipse中Tuscany的配置。

创建你的第一个综合服务程序

 

 接下来,将向你展示你即将创建的综合服务程序的综合示意图。 

 

你将创建的综合服务程序包括4个服务。所提供的综合服务是一个网上店铺。
这有一个你可以用来查询目录项的目录服务,根据货币代码配置它可以提供目录项的美元或者欧元价格。目录服务并不自己进行外汇汇兑,而是通过汇兑服务来做这项工作。这里还有购物车服务,从目录服务中选择的条目都可以被添加到其中,它被作为一个REST服务来实现的,目录服务结合JSONRPC协议实现,而购物车服务结合ATOM协议实现. 最后,这里还有一个面向用户服务,它提供基于商铺用户界面的浏览服务.商铺服务通过JSONRPC协议和ATOM协议分别使用目录服务、购物车服务。

创建一个Java工程

在这一步,你将在Eclipse中创建一个Java项目来管理这个综合服务程序。

点击工具条上的新建Java工程按钮,打开工程创建对话框。然后输入“store”作为工程名,然后在Project Layout 中选择Create separate folders for sources and class files

 点击Next 按钮,然后在下一界面进入Libraries 标签页。点击右侧Add Library...按钮,为工程添加TUSCANY用户库。

 

点击Finish 按钮,结束新建Java工程对话框,完成“store”工程的创建。

 

构建服务

首先,你需要创建2个源码包文件夹,在稍后的步骤里你将在这2个源码包中实现你的服务。
选中”store”工程,点击工具条上的新建Java包文件夹按钮打开新建包文件夹对话框。然后输入”services”作为包文件夹名,点击Finish按钮完成包文件夹的创建。

 

重复之前的步骤创建另一个包为”ufservices”包文件夹。现在”store”工程应该看起来如下图:

接下来,你将在”services”包中实现综合服务程序的常规服务,而在”ufservices”包中实现综合服务程序的用户交互服务。

目录服务

这一步,你将创建目录服务接口并实现它。
选中”services”包文件夹。然后点击新建Java类按钮旁边的下拉箭头,从下拉菜单中选中新建接口选项。在对话框中输入”Catalog”作为接口名,点击Finish按钮关闭对话框。Java编辑器将打开一个新的接口编辑窗口,使用下面代码覆盖编辑窗口原有代码。

package services;

import org.osoa.sca.annotations.Remotable;

@Remotable
public interface Catalog {
	Item[] get();
}

再次选中"services"包文件夹,点击新建Java类按钮。在对话框中输入"CatalogImpl"作为类名,并引入” Catalog”接口,然后点击Finish按钮关闭对话框。

Java编辑器将打开一个新的类编辑窗口,使用下面代码覆盖编辑窗口原有代码。

package services;

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<Item> catalog = new ArrayList<Item>();

	@Init
	public void init() {
		String currencySymbol = currencyConverter
				.getCurrencySymbol(currencyCode);
		catalog.add(new Item("Apple", currencySymbol
				+ currencyConverter.getConversion("USD", currencyCode, 2.99)));
		catalog.add(new Item("Orange", currencySymbol
				+ currencyConverter.getConversion("USD", currencyCode, 3.55)));
		catalog.add(new Item("Pear", currencySymbol
				+ currencyConverter.getConversion("USD", currencyCode, 1.55)));
	}

	public Item[] get() {
		Item[] catalogArray = new Item[catalog.size()];
		catalog.toArray(catalogArray);
		return catalogArray;
	}
}


完成上述步骤后,”store”工程应该看起来如下图,

提示: 类” CatalogImpl”上的红叉是因为我们还没有实现它引用”CurrencyConverter”接口。

汇兑服务

 在这一步中,你将创建汇兑服务接口并实现它。
依照前边你所学到的步骤创建接口并实现。首先在”services”包中创建一个名为"CurrencyConverter"的接口。使用下面代码覆盖原有代码。

package services;

import org.osoa.sca.annotations.Remotable;


@Remotable
public interface CurrencyConverter {
    public double getConversion(String fromCurrenycCode, String toCurrencyCode, double amount);

    public String getCurrencySymbol(String currencyCode);
}

接下来在”services”包中创建一个名为"CurrencyConverterImpl" 的Java类,并使用下面代码覆盖原有代码。

package services;

public class CurrencyConverterImpl implements CurrencyConverter {
	public double getConversion(String fromCurrencyCode, String toCurrencyCode,
			double amount) {
		if (toCurrencyCode.equals("USD"))
			return amount;
		else if (toCurrencyCode.equals("EUR"))
			return ((double) Math.round(amount * 0.7256 * 100)) / 100;
		return 0;
	}

	public String getCurrencySymbol(String currencyCode) {
		if (currencyCode.equals("USD"))
			return "$";
		else if (currencyCode.equals("EUR"))
			return "E"; // "€";
		return "?";
	}
}



完成上述步骤后,"store"工程应该看起来如下图所示。

 

购物车服务

 

在这一步中,你将创建Item、Cart和Total服务接口,以及实现ShoppingCart类。
重复之前学到的方式创建接口并实现它们。

首先在 "services"包中创建名为"Item"的Java类,并复制下面的代码覆盖原有代码。

package services;

public class Item {
	private String name;
	private String price;

	public Item() {
	}

	public Item(String name, String price) {
		this.name = name;
		this.price = price;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPrice() {
		return price;
	}

	public void setPrice(String price) {
		this.price = price;
	}
}



在 "services"包中创建名为" Cart "的Java接口,并复制下面的代码覆盖原有代码。

package services;

import org.apache.tuscany.sca.data.collection.Collection;
import org.osoa.sca.annotations.Remotable;

@Remotable
public interface Cart extends Collection<String, Item> {

}

在 "services"包中创建名为" Total "的Java接口,并复制下面的代码覆盖原有代码.

package services;

import org.osoa.sca.annotations.Remotable;

@Remotable
public interface Total {
        String getTotal();
}

在 "services"包中创建名为" ShoppingCartImpl "的Java类,并复制下面的代码覆盖原有代码。

package services;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.tuscany.sca.data.collection.Entry;
import org.apache.tuscany.sca.data.collection.NotFoundException;
import org.osoa.sca.annotations.Init;
import org.osoa.sca.annotations.Scope;

@Scope("COMPOSITE")
public class ShoppingCartImpl implements Cart, Total {

	private Map<String, Item> cart;

	@Init
	public void init() {
		cart = new HashMap<String, Item>();
	}

	public Entry<String, Item>[] getAll() {
		Entry<String, Item>[] entries = new Entry[cart.size()];
		int i = 0;
		for (Map.Entry<String, Item> e : cart.entrySet()) {
			entries[i++] = new Entry<String, Item>(e.getKey(), e.getValue());
		}
		return entries;
	}

	public Item get(String key) throws NotFoundException {
		Item item = cart.get(key);
		if (item == null) {
			throw new NotFoundException(key);
		} else {
			return item;
		}
	}

	public String post(String key, Item item) {
		if (key == null) {
			key = "cart-" + UUID.randomUUID().toString();
		}
		cart.put(key, item);
		return key;
	}

	public void put(String key, Item item) throws NotFoundException {
		if (!cart.containsKey(key)) {
			throw new NotFoundException(key);
		}
		cart.put(key, item);
	}

	public void delete(String key) throws NotFoundException {
		if (key == null || key.equals("")) {
			cart.clear();
		} else {
			Item item = cart.remove(key);
			if (item == null)
				throw new NotFoundException(key);
		}
	}

	public Entry<String, Item>[] query(String queryString) {
		List<Entry<String, Item>> entries = new ArrayList<Entry<String, Item>>();
		if (queryString.startsWith("name=")) {
			String name = queryString.substring(5);
			for (Map.Entry<String, Item> e : cart.entrySet()) {
				Item item = e.getValue();
				if (item.getName().equals(name)) {
					entries.add(new Entry<String, Item>(e.getKey(), e
							.getValue()));
				}
			}
		}
		return entries.toArray(new Entry[entries.size()]);
	}

	public String getTotal() {
		double total = 0;
		String currencySymbol = "";
		if (!cart.isEmpty()) {
			Item item = cart.values().iterator().next();
			currencySymbol = item.getPrice().substring(0, 1);
		}
		for (Item item : cart.values()) {
			total += Double.valueOf(item.getPrice().substring(1));
		}
		return currencySymbol + String.valueOf(total);
	}
}


提示: 由于Tuscany尚未支持会话服务,因此cart被作为一个黑盒实现。cart被定义为静态的。

完成上述步骤后,工程”store”将看起来如下图所示。

商铺服务

在这一步中,你将创建面向用户服务,他可以通过Web浏览器访问,并提供与你创建的其他服务相交互的接口。 

选中"ufservices" 包文件夹,右键点击,在右键菜单中选择New -> File 。在新建文件对话框中输入"store.html"作为文件名,然后点Finish按钮关闭对话框。

文本编辑器将打开一个新的文件编辑窗口,使用下面Html代码覆盖原有代码。 

<html>
<head>
<title>Store</title>

<script type="text/javascript" src="store.js"></script>

<script language="JavaScript">

	//@Reference
	var catalog = new tuscany.sca.Reference("catalog");
	
	//@Reference
	var shoppingCart = new tuscany.sca.Reference("shoppingCart");

	//@Reference
	var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
	
	var catalogItems;

	function catalog_getResponse(items) {
		var catalog = "";
		for (var i=0; i<items.length; i++) {
			var item = items[i].name + ' - ' + items[i].price;
			catalog += '<input name="items" type="checkbox" value="' + 
						item + '">' + item + ' <br>';
		}
		document.getElementById('catalog').innerHTML=catalog;
		catalogItems = items;
	}
	
	function shoppingCart_getResponse(feed) {
		if (feed != null) {
			var entries = feed.getElementsByTagName("entry");              
			var list = "";
			for (var i=0; i<entries.length; i++) {
				var content = entries[i].getElementsByTagName("content")[0];
				var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
				var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
				list += name + ' - ' + price + ' <br>';
			}
			document.getElementById("shoppingCart").innerHTML = list;

			if (entries.length != 0) {			
				shoppingTotal.getTotal(shoppingTotal_getTotalResponse);
			}
		}
	}
	
	function shoppingTotal_getTotalResponse(total) {
		document.getElementById('total').innerHTML = total;
	}
	
	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>item</title><content type="text/xml">' +
                	'<Item xmlns="http://services/">' +
                	'<name xmlns="">' + catalogItems[i].name + '</name>' + '<price xmlns="">' + catalogItems[i].price + '</price>' +
                 	'</Item>' + '</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">'+
					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('shoppingCart').innerHTML = "";
		document.getElementById('total').innerHTML = "";	
	}	

	function init() {
		catalog.get(catalog_getResponse);
		shoppingCart.get("", shoppingCart_getResponse);
	}
	
</script>

</head>

<body onload="init()">
<h1>Store</h1>
  <div id="store">
   	<h2>Catalog</h2>
   	<form name="catalogForm">
		<div id="catalog" ></div>
		<br>
		<input type="button" onClick="addToCart()"  value="Add to Cart">
   	</form>
 
 	<br>
  
   	<h2>Your Shopping Cart</h2>
   	<form name="shoppingCartForm">
		<div id="shoppingCart"></div>
		<br>
		<div id="total"></div>
		<br>		
		<input type="button" onClick="checkoutCart()" value="Checkout"> 
		<input type="button" onClick="deleteCart()" value="Empty">     
	   	<a href="../ShoppingCart/Cart/">(feed)</a>
	</form>    
  </div>
</body>
</html>

 完成这些步骤后,"store"工程将看起来如下图所示

组织服务

 

既然你已经实现了所有必须的服务,那么你可以把他们组织在一起,提供商铺综合服务。结构配置存储在一个后缀为.composite的文件中。

选中"store"工程的"src"文件夹,右键点击,在右键菜单中选择New-> File,在新建文件对话框中输入”store.composite”作为文件名,然后点击Finish 按钮关闭对话框。

文本编辑器将打开一个新的文件编辑窗口来创建结构配置文件,使用下面内容覆盖原有代码。

<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
	xmlns:s="http://store" 
	targetNamespace="http://store" 
	name="store">
	
	<component name="store">
		<t:implementation.widget location="ufservices/store.html" />
		<service name="Widget">
			<t:binding.http uri="http://localhost:8080/store" />
		</service>
		<reference name="catalog" target="Catalog">
			<t:binding.jsonrpc />
		</reference>
		<reference name="shoppingCart" target="ShoppingCart/Cart">
			<t:binding.atom />
		</reference>
		<reference name="shoppingTotal" target="ShoppingCart/Total">
			<t:binding.jsonrpc />
		</reference>
	</component>

	<component name="Catalog">
		<implementation.java class="services.CatalogImpl" />
		<property name="currencyCode">USD</property>
		<service name="Catalog">
			<t:binding.jsonrpc uri="http://localhost:8080/Catalog"/>
		</service>
		<reference name="currencyConverter" target="CurrencyConverter" />
	</component>

	<component name="ShoppingCart">
		<implementation.java class="services.ShoppingCartImpl" />
		<service name="Cart">
			<t:binding.atom uri="http://localhost:8080/ShoppingCart/Cart" />
		</service>
		<service name="Total">
			<t:binding.jsonrpc uri="http://localhost:8080/Total"/>
		</service>
	</component>

	<component name="CurrencyConverter">
		<implementation.java class="services.CurrencyConverterImpl" />
	</component>
</composite>


完成上述步骤后,工程”store”应该看起来如下图所示。

 

 

 

启动服务

在这一步中,你将创建Tuscany运行你建立的综合商铺服务的启动代码。

选中"store"工程,点击工具条上的新建Java源码包按钮,启动新建包文件对话框。使用此对话框创建一个新的名为"launch"的包文件夹。

选中”launch”包,点击新建Java类按钮。在对话框中输入”Launch”作为类名,在复选框中选择创建main方法,然后点击Finish 按钮,结束对话框。

Java编辑器将打开一个新的Java类编辑窗口,使用下面代码覆盖原有代码。

package launch;

import org.apache.tuscany.sca.host.embedded.SCADomain;

public class Launch {
	public static void main(String[] args) throws Exception {
		System.out.println("Starting ...");
		SCADomain scaDomain = SCADomain.newInstance("store.composite");
		System.out.println("store.composite ready for big business !!!");
		System.in.read();
		System.out.println("Stopping ...");
		scaDomain.close();
		System.out.println();
	}
}

恭喜你完成了你的第一个综合服务程序,现在,是时候让它运行了。

使用服务

 

在这一步,你将运行并使用你创建的商铺综合服务程序。 

首先选中"store"工程的"launch"包中的"Launch"类,右键点击,在右键菜单中选中Run As-> Java application ,Tuscany运行环境将启动并加载商铺综合服务程序到它的运行域中。 

Eclipse控制台将输出如下信息:

 

 

 

然后登陆你的浏览器,输入如下网址:

http://localhost:8080/store/store.html

打开综合服务程序的用户交互服务界面。

 

既然购物车服务是结合ATOM协议实现,你也可以通过点击样式切换图标来使用ATOM形式查看销售内容,你得到的ATOM样式:

 

使用浏览器回退按钮,重新回到商铺页面。

 

然后,你可以检查并完成你的订单。

 

 

恭喜你,你已经使用Tuscany SCA技术实现了一个简单的,灵活的,可重复使用的商铺程序。

 

你可能感兴趣的:(使用Eclipse构建Tuscany实例)