simple sample to use as an example when working with students

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@933952 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
slaws 2010-04-14 13:53:18 +00:00
parent a4ec5e3b69
commit efc0be2bc0
10 changed files with 765 additions and 0 deletions

View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-sca</artifactId>
<version>2.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>sandbox-bank-challenge</artifactId>
<name>Apache Tuscany SCA Sandbox Bank Challenge</name>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-sca-api</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-node-api</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-node-impl</artifactId>
<version>2.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-implementation-java-runtime</artifactId>
<version>2.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-binding-ws-runtime-axis2</artifactId>
<version>2.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-webapp</artifactId>
<version>1.5.1</version>
<type>war</type>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/wsimportout</directory>
</resource>
<resource>
<directory>src/wsgenout</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>calculator.CalculatorClient</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package bank;
import java.util.List;
import org.oasisopen.sca.annotation.Remotable;
/**
* The Bank service interface.
*/
@Remotable
public interface BankService {
String createAccount(String customerName);
Statement getStatement(String accountID);
void buyEquity(String accountID, String equityCode, int number);
void sellEquity(String accountID, String equityCode, int number);
StockQuote getStockQuote(String accountID, String equityCode);
List<StockQuote> getAllStockQuotes(String accountID);
}

View file

@ -0,0 +1,143 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package bank;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* A stock quote
*/
public class Statement implements Serializable {
private String customerName;
private String accountID;
private long cashBalance;
private List<StockHolding> stockHoldings;
private List<String> transactions = new ArrayList<String>();
public Statement(){
if (this.stockHoldings == null){
this.stockHoldings = new ArrayList<StockHolding>();
}
}
public Statement(String customerName, String accountID, long cashBalance, List<StockHolding> stockHoldings){
this.customerName = customerName;
this.accountID = accountID;
this.cashBalance = cashBalance;
this.stockHoldings = stockHoldings;
if (this.accountID == null){
this.accountID = UUID.randomUUID().toString();
}
if (this.stockHoldings == null){
this.stockHoldings = new ArrayList<StockHolding>();
}
}
public String getCustomerName() {
return customerName;
}
public String getAccountID() {
return accountID;
}
public long getCashBalance() {
return cashBalance;
}
public void creditCashBalance(long credit, String reason) {
this.cashBalance += credit;
transactions.add("credit " + credit + " : " + reason);
}
public void debitCashBalance(long debit, String reason) {
this.cashBalance -= debit;
transactions.add("debit " + debit + " : " + reason);
}
public List<StockHolding> getStockHolding() {
return stockHoldings;
}
public void creditStockHolding(StockHolding stock){
stockHoldings.add(stock);
debitCashBalance(stock.getPrice() * stock.getNumberHeld(),
"bought " + stock.getNumberHeld() + " of " + stock.getStockCode() + " at " + stock.getPrice());
}
public void debitStockHolding(StockHolding stock){
int numberToSell = stock.getNumberHeld();
int numberSold = 0;
List<StockHolding> toRemove = new ArrayList<StockHolding>();
for (StockHolding stockHolding : stockHoldings){
if (stockHolding.getStockCode().equals(stock.getStockCode())){
if (stockHolding.getNumberHeld() > numberToSell){
stockHolding.setNumberHeld(stockHolding.getNumberHeld() - numberToSell);
numberSold += numberToSell;
numberToSell = 0;
break;
} else {
numberSold += stockHolding.getNumberHeld();
numberToSell -= stockHolding.getNumberHeld();
stockHolding.setNumberHeld(0);
toRemove.add(stockHolding);
}
}
}
stockHoldings.removeAll(toRemove);
creditCashBalance(stock.getPrice() * numberSold,
"sold " + numberSold + " of " + stock.getStockCode() + " at " + stock.getPrice());
}
public List<String> getTransactions() {
return transactions;
}
@Override
public String toString() {
String returnString =
"customer name = " + customerName +
"\naccount Id = " + accountID +
"\nbalance = " + cashBalance +
"\nequities = \n";
for (StockHolding stock : stockHoldings){
returnString += " stock " + stock.getStockCode() + " number held = " + stock.getNumberHeld() + "\n";
}
returnString +=
"transactions = \n";
for(String transaction : transactions){
returnString += " " + transaction + "\n";
}
return returnString;
}
}

View file

@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package bank;
import java.io.Serializable;
/**
* A stock quote
*/
public class StockHolding implements Serializable {
private String stockCode;
private int numberHeld;
private long price;
public StockHolding(String stockCode, int numberHeld, long price){
this.stockCode = stockCode;
this.numberHeld = numberHeld;
this.price = price;
}
public String getStockCode() {
return stockCode;
}
public int getNumberHeld() {
return numberHeld;
}
public void setNumberHeld(int numberHeld) {
this.numberHeld = numberHeld;
}
public long getPrice() {
return price;
}
@Override
public String toString() {
return stockCode + " - number=" + numberHeld + " - price=" + price;
}
}

View file

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package bank;
import java.io.Serializable;
/**
* A stock quote
*/
public class StockQuote implements Serializable {
private String stockCode;
private long stockQuote;
public StockQuote(String stockCode, long stockQuote){
this.stockCode = stockCode;
this.stockQuote = stockQuote;
}
public String getStockCode() {
return stockCode;
}
public long getStockQuote() {
return stockQuote;
}
public void setStockQuote(long stockQuote) {
this.stockQuote = stockQuote;
}
@Override
public String toString() {
return stockCode + " - " + stockQuote;
}
}

View file

@ -0,0 +1,180 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package bank.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import org.oasisopen.sca.annotation.Scope;
import org.oasisopen.sca.annotation.Service;
import bank.BankService;
import bank.Statement;
import bank.StockHolding;
import bank.StockQuote;
/**
* An implementation of the Bank service.
*/
@Service(BankService.class)
@Scope("COMPOSITE")
public class BankServiceImpl implements BankService {
protected int initialCredit = 1000;
protected int overdrawnCost = 1;
protected int statementCost = 1;
protected int stockQuoteCost = 1;
protected int stockTransactionCost = 1;
private List<StockQuote> stocks = new ArrayList<StockQuote>();
private List<Statement> accounts = new ArrayList<Statement>();
private Random generator = new Random();
private HashMap<String, StockQuote> stockMap = new HashMap<String, StockQuote>();
private HashMap<String, Statement> accountMap = new HashMap<String, Statement>();
public BankServiceImpl(){
// TODO - Data to come from composite file
// initial stocks
stocks.add(new StockQuote("ABC", 100));
stocks.add(new StockQuote("DEF", 123));
stocks.add(new StockQuote("GHI", 543));
// initial users
accounts.add(new Statement("SL", null, 0, null));
accounts.add(new Statement("AE", null, 0, null));
accounts.add(new Statement("KG", null, 0, null));
// create map for easy access
for (StockQuote stock : stocks){
stockMap.put(stock.getStockCode(), stock);
}
}
// public interface
public String createAccount(String customerName) {
for (Statement statement : accounts){
if (statement.getCustomerName().equals(customerName)){
accountMap.put(statement.getAccountID(), statement);
statement.getTransactions().add("account created");
statement.creditCashBalance(initialCredit, "starting balance");
return statement.getAccountID();
}
}
return "Customer Name Not Found";
}
public Statement getStatement(String accountID) {
Statement statement = accountMap.get(accountID);
if(statement != null){
statement.debitCashBalance(statementCost, "retrieved statement");
if (statement.getCashBalance() < 0){
statement.debitCashBalance(overdrawnCost, "account overdrawn");
}
}
return statement;
}
public void buyEquity(String accountID, String equityCode, int number) {
updateStockPrices();
StockQuote stock = stockMap.get(equityCode);
if (stock == null){
return;
}
long cost = stock.getStockQuote() * number;
Statement statement = accountMap.get(accountID);
if(statement != null){
if (statement.getCashBalance() > cost){
StockHolding stockHolding = new StockHolding(equityCode, number, stock.getStockQuote());
statement.creditStockHolding(stockHolding);
statement.debitCashBalance(stockTransactionCost, "stock transaction (buy) " + equityCode);
}
}
}
public void sellEquity(String accountID, String equityCode, int number) {
updateStockPrices();
StockQuote stock = stockMap.get(equityCode);
if (stock == null){
return;
}
Statement statement = accountMap.get(accountID);
if(statement != null){
StockHolding stockHolding = new StockHolding(equityCode, number, stock.getStockQuote());
statement.debitStockHolding(stockHolding);
statement.debitCashBalance(stockTransactionCost, "stock transaction (sell) " + equityCode);
}
}
public StockQuote getStockQuote(String accountID, String equityCode) {
updateStockPrices();
Statement statement = accountMap.get(accountID);
StockQuote stockQuote = null;
if(statement != null){
statement.debitCashBalance(stockQuoteCost, "stock quote");
if (statement.getCashBalance() < 0){
statement.debitCashBalance(overdrawnCost, "account overdrawn");
}
stockQuote = stockMap.get(equityCode);
}
return stockQuote;
}
public List<StockQuote> getAllStockQuotes(String accountID) {
updateStockPrices();
Statement statement = accountMap.get(accountID);
List<StockQuote> stockQuote = null;
if(statement != null){
statement.debitCashBalance(stockQuoteCost * stocks.size(), "stock quote");
if (statement.getCashBalance() < 0){
statement.debitCashBalance(overdrawnCost, "account overdrawn");
}
stockQuote = stocks;
}
return stockQuote;
}
// private functions
private void updateStockPrices(){
for (StockQuote stock : stocks){
long stockQuote = stock.getStockQuote();
stockQuote += (generator.nextInt(10) - 5);
stock.setStockQuote(stockQuote);
}
}
}

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
targetNamespace="http://banking-challenge"
xmlns:sample="http://banking-challenge"
name="Bank">
<component name="BankServiceComponent">
<implementation.java class="bank.impl.BankServiceImpl"/>
<service name="BankService">
</service>
</component>
</composite>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<contribution xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:sample="http://banking-challenge">
<deployable composite="sample:Bank"/>
</contribution>

View file

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package test;
import static org.junit.Assert.assertEquals;
import org.apache.tuscany.sca.node.Node;
import org.apache.tuscany.sca.node.NodeFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import bank.BankService;
/**
* Test the Bank service component.
*/
public class BankTestCase{
private static Node node;
private static BankService bankService;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
node = NodeFactory.newInstance().createNode((String)null, new String[] {"target/classes"}).start();
bankService = node.getService(BankService.class, "BankServiceComponent");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
node.stop();
}
@Test
public void testCalculator() throws Exception {
String accountID = bankService.createAccount("SL");
System.out.println("AccountID " + accountID + "\n");
System.out.println("Statement\n" + bankService.getStatement(accountID));
System.out.println("All stock quotes\n" + bankService.getAllStockQuotes(accountID) + "\n");
bankService.buyEquity(accountID, "ABC", 10);
System.out.println("Statement\n" + bankService.getStatement(accountID));
bankService.sellEquity(accountID, "ABC", 5);
System.out.println("Statement\n" + bankService.getStatement(accountID));
}
}

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-sca</artifactId>
<version>2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>tuscany-bank-challenge</artifactId>
<packaging>pom</packaging>
<name>Apache Tuscany SCA Bank Challenge</name>
<repositories>
<repository>
<id>apache.incubator</id>
<url>http://people.apache.org/repo/m2-incubating-repository</url>
</repository>
</repositories>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>bank-contribution</module>
<module>client-sl-contribution</module>
<module>launcher</module>
</modules>
</profile>
</profiles>
</project>