[jboss-cvs] JBossAS SVN: r62854 - in projects/aop/trunk/aop/docs/examples: finally and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue May 8 02:10:55 EDT 2007
Author: flavia.rainone at jboss.com
Date: 2007-05-08 02:10:55 -0400 (Tue, 08 May 2007)
New Revision: 62854
Added:
projects/aop/trunk/aop/docs/examples/finally/
projects/aop/trunk/aop/docs/examples/finally/Account.java
projects/aop/trunk/aop/docs/examples/finally/Bank.java
projects/aop/trunk/aop/docs/examples/finally/Driver.java
projects/aop/trunk/aop/docs/examples/finally/FinallyAspect.java
projects/aop/trunk/aop/docs/examples/finally/InvalidBalanceException.java
projects/aop/trunk/aop/docs/examples/finally/MutexAspect.java
projects/aop/trunk/aop/docs/examples/finally/NoSuchAccountException.java
projects/aop/trunk/aop/docs/examples/finally/Parser.java
projects/aop/trunk/aop/docs/examples/finally/Transaction.java
projects/aop/trunk/aop/docs/examples/finally/build.xml
projects/aop/trunk/aop/docs/examples/finally/finally.html
projects/aop/trunk/aop/docs/examples/finally/input.txt
projects/aop/trunk/aop/docs/examples/finally/jboss-aop.xml
Modified:
projects/aop/trunk/aop/docs/examples/examples.html
Log:
[JBAOP-381] Tutorial example for finally advices.
Modified: projects/aop/trunk/aop/docs/examples/examples.html
===================================================================
--- projects/aop/trunk/aop/docs/examples/examples.html 2007-05-08 01:13:50 UTC (rev 62853)
+++ projects/aop/trunk/aop/docs/examples/examples.html 2007-05-08 06:10:55 UTC (rev 62854)
@@ -31,6 +31,7 @@
<li> <a href="annotated-parameters/annotated-parameters.html">Annotated advice parameters</a></li>
<li> <a href="return-types/return-types.html">Advice return types</a></li>
<li> <a href="after-throwing/after-throwing.html">After-throwing advices</a></li>
+<li> <a href="finally/finally.html">Finally advices</a></li>
<li> <a href="overloaded-advices/overloaded-advices.html">Overloaded advices</a></li>
<li> <a href="precedence/precedence.html">Interceptor precedence</a></li>
<li> <a href="introductions/introductions.html">Introductions</a></li>
Added: projects/aop/trunk/aop/docs/examples/finally/Account.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/Account.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/Account.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+public class Account
+{
+ public String name;
+ public double value;
+
+ public Account(String name, double value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void sumAmount(double amount) throws InvalidBalanceException
+ {
+ this.value += amount;
+ if (this.value < 0.0)
+ {
+ InvalidBalanceException exception = new InvalidBalanceException("negative balance not allowed " + Bank.CURRENCY.format(amount));
+ // undo
+ value -= amount;
+ throw exception;
+ }
+ }
+
+ public String toString()
+ {
+ return name + ": " + Bank.CURRENCY.format(value);
+ }
+}
\ No newline at end of file
Added: projects/aop/trunk/aop/docs/examples/finally/Bank.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/Bank.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/Bank.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Bank
+{
+ public static final NumberFormat CURRENCY = NumberFormat.getCurrencyInstance();
+
+ private Map<String,Account> accounts = new HashMap<String,Account>();
+
+ public void createAccount(String name, double amount)
+ {
+ System.out.println("Creating account \'" + name + "\' with initial balance of $" + amount);
+ accounts.put(name, new Account(name, amount));
+ }
+
+ public void printAccounts()
+ {
+ for (Account account: accounts.values())
+ {
+ System.out.println(account);
+ }
+ }
+
+ public Transaction getDepositTransaction(String accountName)
+ throws NoSuchAccountException
+ {
+ return new Deposit(getAccount(accountName));
+ }
+
+ public Transaction getWithdrawalTransaction(String accountName)
+ throws NoSuchAccountException
+ {
+ return new Withdrawal(getAccount(accountName));
+ }
+
+ public Transaction getWireTransferTransaction(String fromAccountName,
+ String toAccountName) throws NoSuchAccountException
+ {
+ return new WireTransfer(getAccount(fromAccountName), getAccount(toAccountName));
+ }
+
+ private Account getAccount(String name) throws NoSuchAccountException
+ {
+ if (!accounts.containsKey(name))
+ {
+ throw new NoSuchAccountException("Account named '" + name + "' does not exist.");
+ }
+ return accounts.get(name);
+ }
+}
\ No newline at end of file
Added: projects/aop/trunk/aop/docs/examples/finally/Driver.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/Driver.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/Driver.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class Driver
+{
+ public static void main(String[] args) throws Exception
+ {
+ // open file
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream("input.txt")));
+ // create bank
+ Bank bank = new Bank();
+
+ // parse file
+ System.out.println();
+ System.out.println("SETUP");
+ System.out.println("=====");
+ Parser parser = new Parser();
+ parser.parseAccountSetup(bank, reader);
+ Collection<Transaction> transactions = parser.parseTransactions(bank, reader);
+
+
+ // create transaction threads
+ Collection<Thread> threads = new ArrayList<Thread>();
+ for (Transaction transaction: transactions)
+ {
+ threads.add(new Thread(transaction, transaction.toString()));
+ }
+
+ // execute transaction threads
+ System.out.println();
+ System.out.println("TRANSACTIONS");
+ System.out.println("============");
+ for (Thread thread: threads)
+ {
+ thread.start();
+ }
+
+ // join transaction threads
+ for (Thread thread: threads)
+ {
+ thread.join();
+ }
+
+ // print final balance
+ System.out.println();
+ System.out.println("FINAL BALANCE");
+ System.out.println("===== =======");
+ bank.printAccounts();
+ }
+}
\ No newline at end of file
Added: projects/aop/trunk/aop/docs/examples/finally/FinallyAspect.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/FinallyAspect.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/FinallyAspect.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import org.jboss.aop.advice.annotation.Arg;
+import org.jboss.aop.advice.annotation.Return;
+import org.jboss.aop.advice.annotation.Thrown;
+
+public class FinallyAspect
+{
+ public void finallyAdvice1(@Thrown Throwable thrownException)
+ {
+ System.out.println(">>> finallyAdvice1 Exception has been thrown: " + (thrownException != null));
+ }
+
+ public void finallyAdvice2(@Return Account account,
+ @Thrown Throwable thrownException, @Arg String queriedName)
+ {
+ if (thrownException == null)
+ {
+ System.out.println(">>> finallyAdvice2 Account retrieved: " + account);
+ }
+ else
+ {
+ System.out.println(">>> finallyAdvice2 Account '" + queriedName +
+ "' not found");
+ }
+ }
+}
Added: projects/aop/trunk/aop/docs/examples/finally/InvalidBalanceException.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/InvalidBalanceException.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/InvalidBalanceException.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+public class InvalidBalanceException extends Exception {
+
+ public InvalidBalanceException(String message)
+ {
+ super(message);
+ }
+}
\ No newline at end of file
Added: projects/aop/trunk/aop/docs/examples/finally/MutexAspect.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/MutexAspect.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/MutexAspect.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import org.jboss.aop.advice.annotation.JoinPoint;
+import org.jboss.aop.advice.annotation.Thrown;
+
+import org.jboss.aop.JoinPointInfo;
+
+public class MutexAspect
+{
+ private Object lock = new Object();
+ private boolean locked = false;
+
+ public void beforeAdvice(@JoinPoint JoinPointInfo joinPoint)
+ {
+ synchronized(lock)
+ {
+ while (locked)
+ {
+ try
+ {
+ lock.wait();
+ }
+ catch(InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ return;
+ }
+ }
+ locked = true;
+ System.out.println(">>> Retrieved concurrency lock");
+ }
+ }
+
+ public void finallyAdvice(@JoinPoint JoinPointInfo joinPoint)
+ {
+ synchronized(lock)
+ {
+ locked = false;
+ lock.notifyAll();
+ System.out.println("<<< Releasing concurrency lock");
+ }
+ }
+}
Added: projects/aop/trunk/aop/docs/examples/finally/NoSuchAccountException.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/NoSuchAccountException.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/NoSuchAccountException.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+public class NoSuchAccountException extends Exception
+{
+ public NoSuchAccountException(String message)
+ {
+ super(message);
+ }
+}
Added: projects/aop/trunk/aop/docs/examples/finally/Parser.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/Parser.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/Parser.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,148 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class Parser
+{
+ private int lineNumber = 0;
+ private int index = 0;
+
+ public void parseAccountSetup(Bank bank, BufferedReader reader) throws IOException
+ {
+ String line = reader.readLine().trim();
+
+ while (line.length() > 0)
+ {
+ // read name and initial balance
+ String accountName = readAccountName(line, "an amount");
+ double balanceValue = readAmount(line);
+
+ // create account
+ bank.createAccount(accountName, balanceValue);
+
+ lineNumber ++;
+ line = reader.readLine().trim();
+ }
+ }
+
+ public Collection<Transaction> parseTransactions(Bank bank, BufferedReader reader)
+ throws IOException
+ {
+ Collection<Transaction> transactions = new ArrayList<Transaction>();
+
+ lineNumber ++;
+ String line = reader.readLine().trim();
+
+ while (line.length() > 0)
+ {
+ // read first string
+ String accountName = readAccountName(line, "an operation");
+ Transaction transaction = null;
+ try
+ {
+ // if first string contains a transfer (A->B, for example)
+ int transferIndex = accountName.indexOf("->");
+ if (transferIndex != -1)
+ {
+ // create wire transfer
+ String fromAccountName = accountName.substring(0, transferIndex);
+ String toAccountName = accountName.substring(transferIndex + 2);
+ transaction = bank.getWireTransferTransaction(fromAccountName, toAccountName);
+ }
+ else
+ {
+ // create deposit or withdrawal
+ switch(line.charAt(++index))
+ {
+ case '+':
+ transaction = bank.getDepositTransaction(accountName);
+ break;
+ case '-':
+ transaction = bank.getWithdrawalTransaction(accountName);
+ break;
+ default:
+ System.err.println("Unexpected character at line " + lineNumber +
+ ". Should be \'+\' or \'-\', to indicate deposit and withdrawal transactions, respectively.");
+ System.exit(1);
+ }
+ }
+ // read and set transaction amount
+ double amount = readAmount(line);
+ transaction.setAmount(amount);
+
+ // add transaction to collection
+ transactions.add(transaction);
+ }
+ catch(NoSuchAccountException e)
+ {
+ System.out.println("ERROR invalid transaction: " + e.getMessage());
+ }
+
+
+
+ lineNumber ++;
+ line = reader.readLine().trim();
+ }
+ // return collection of created transactions
+ return transactions;
+ }
+
+ private String readAccountName(String line, String afterAccount)
+ {
+ index = line.indexOf(' ');
+ if (index == -1)
+ {
+ System.err.println("Line " + lineNumber +
+ " should either contain an account name, followed by " + afterAccount +
+ ", or be empty.");
+ System.exit(1);
+ }
+ return line.substring(0, index);
+ }
+
+ private double readAmount(String line)
+ {
+ if (line.charAt(++ index) != '$')
+ {
+ System.err.println("Line " + lineNumber
+ + " is missing \'$\' before amount value");
+ System.exit(1);
+ }
+
+ try
+ {
+ return Double.parseDouble(line.substring(index + 1));
+ }
+ catch (NumberFormatException e)
+ {
+ System.err.println("Cannot read amount value in line " + lineNumber +
+ ": " + e);
+ System.exit(1);
+ }
+ return 0.0;
+ }
+}
\ No newline at end of file
Added: projects/aop/trunk/aop/docs/examples/finally/Transaction.java
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/Transaction.java (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/Transaction.java 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,118 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+public abstract class Transaction implements Runnable
+{
+ protected double amount;
+
+ public void setAmount(double amount)
+ {
+ this.amount = amount;
+ }
+
+ protected abstract void execute() throws InvalidBalanceException;
+
+ public void run()
+ {
+ try
+ {
+ this.execute();
+ }
+ catch(InvalidBalanceException e)
+ {
+ System.out.print("ERROR can't perform operation because it results in: ");
+ System.out.println(e.getMessage());
+ }
+ System.out.println("---");
+ }
+}
+
+class Deposit extends Transaction
+{
+ private Account account;
+
+ public Deposit(Account account)
+ {
+ this.account = account;
+ }
+
+ protected void execute() throws InvalidBalanceException
+ {
+ System.out.println("Depositing " + Bank.CURRENCY.format(amount) +
+ " to account " + account.getName());
+ account.sumAmount(amount);
+ }
+
+ public String toString()
+ {
+ return "DEPOSIT: " + account.getName() + " " + Bank.CURRENCY.format(amount);
+ }
+}
+
+class Withdrawal extends Transaction
+{
+ private Account account;
+
+ public Withdrawal(Account account)
+ {
+ this.account = account;
+ }
+
+ protected void execute() throws InvalidBalanceException
+ {
+ System.out.println("Withdrawing " + Bank.CURRENCY.format(amount) +
+ " from account " + account.getName());
+ account.sumAmount(-amount);
+ }
+
+ public String toString()
+ {
+ return "WITHDRAWAL: " + account.getName() + " " + Bank.CURRENCY.format(amount);
+ }
+}
+
+class WireTransfer extends Transaction
+{
+ private Account fromAccount;
+ private Account toAccount;
+
+ public WireTransfer(Account fromAccount, Account toAccount)
+ {
+ this.fromAccount = fromAccount;
+ this.toAccount = toAccount;
+ }
+
+ protected void execute() throws InvalidBalanceException
+ {
+ System.out.println("Transfering " + Bank.CURRENCY.format(amount) +
+ " from account " + fromAccount.getName() +
+ " to account " + toAccount.getName());
+ fromAccount.sumAmount(-amount);
+ toAccount.sumAmount(amount);
+ }
+
+ public String toString()
+ {
+ return "TRANSFER: " + fromAccount.getName() + "->" + toAccount.getName() +
+ " " + Bank.CURRENCY.format(amount);
+ }
+}
\ No newline at end of file
Added: projects/aop/trunk/aop/docs/examples/finally/build.xml
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/build.xml (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/build.xml 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="usage" name="JBoss/AOP">
+ <import file="../examples-build.xml"/>
+
+ <target name="run.aopc.50" depends="_run.aopc.50"/>
+
+ <target name="run.loadtime.50" depends="_run.loadtime.50"/>
+
+ <target name="run.aopc.14" depends="_run.aopc.14.retro"/>
+
+ <target name="run.loadtime.14" depends="_run.loadtime.14.retro"/>
+</project>
Added: projects/aop/trunk/aop/docs/examples/finally/finally.html
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/finally.html (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/finally.html 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,346 @@
+<html>
+<body>
+<p>
+<h2>Finally Advices</h2>
+
+</p><p>
+<h3>Overview</h3>
+
+The fifth type of adivce that JBoss AOP provides is the finally advice. In this
+example we will see how to write finally advices and when they are invoked.
+</p><p>
+<h3>Advices Invocation in JBoss AOP</h3>
+
+</p><p>
+When intercepting a joinpoint, one can write after and after-throwing advices
+to perform an interception after the joinpoint execution. However, the execution
+of these advices is not assured. If the joinpoint executes normally, an after advice
+will be invoked, but the after-throwing one will not. On the other hand, when the
+joinpoint throws an exception, all after advices are skipeed while advices of
+after-throwing type will be invoked.
+</p><p>
+Finally advices are a mixture of after advices and after-throwing advices.
+As is the case of both advices, finally advices are also invoked after the joinpoint
+execution. But finally advices are the only type of advice that is invoked after
+joinpoint execution independently of its outcome. Since finally advices are invoked
+from inside a finally block, they will always be executed.
+</p><p>
+To understand better this mechanism, refer to the following:
+<pre>
+
+0 try
+1 {
+2 call before advices
+3 call around advices
+4 call after advices
+6 }
+7 catch(Throwable t)
+8 {
+9 call after-throwing advices
+10 throw t;
+11 }
+12 finally
+13 {
+14 call finally advices
+15 }
+</pre>
+</p><p>
+This is a simplified view of how JBoss AOP invokes the several types of
+advices. Before advices are executed before everything else. Next, around advices are
+called. Since around advices are responsible for triggering the joinpoint execution,
+this execution is wrapped in line 3. After advices are called next. After-throwing
+advices follow inside a catch block and, finally advices, inside a finally block. As
+we can see, the advices that are called after a joinpoint execution depend
+on how the joinpoint returns. If the joinpoint throws an exception, after advices
+will be skipped and the control flow will be directed to the catch block, where
+after-throwing advices are invoked. And, after that, we follow to the finally block,
+where finally advices are executed. Lastly, the <tt>Throwable t</tt> is rethrown. But if,
+on the other hand, the joinpoint execution returns normally, the control flow will
+follow from around to after advices. Next, the catch block is skipped and the finally
+block executed.
+</p><p>
+<h2> Writing Finally Advices</h2>
+
+</p><p>
+Finally advices must follow the annotated-parameters, signature:
+<pre>
+public <return-value> <any-method-name>(@<Annotation> <any type> arg0, @<Annotation> <any type> arg1, ... , @<Annotation> <any type> argN) throws <Exception1>,<Exception2>,...,<ExceptionN>
+</pre>
+</p><p>
+The annotated parameters can be of all types previously seen.
+</p><p>
+To bind a finally advice, just use the finally tag as below:
+</p><p>
+<pre>
+<bind pointcut="execution(* POJO->*(..))">
+ <throwing name="finallyAdvice" aspect="Aspect"/>
+</bind>
+</pre>
+</p><p>
+<h2> Mutex Example Revisited</h2>
+
+</p><p>
+Let's revisit the first example of
+<a href="../beforeafter/beforeafter.html">before/after advices</a>. In that example, we wrote
+a <tt>MutexAspect</tt> to assure that several concurrent bank transactions could be run in
+a synchronized manner. The <tt>MutexAspect</tt> was composed by a pair of related
+before/after advices. The before advice would retrieve the mutex lock, that would be
+released by the after advice:
+</p><p>
+<pre>
+public class MutexAspect
+{
+ private Object lock = new Object();
+ private boolean locked = false;
+
+ public void beforeAdvice(@JoinPoint Joinpoint joinPoint)
+ {
+ synchronized(lock)
+ {
+ while (locked)
+ {
+ try
+ {
+ lock.wait();
+ }
+ catch(InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ return;
+ }
+ }
+ locked = true;
+ System.out.println(">>> Retrieved concurrency lock");
+ }
+ }
+
+ public void afterAdvice(@JoinPoint Joinpoint joinPoint)
+ {
+ synchronized(lock)
+ {
+ locked = false;
+ lock.notify();
+ System.out.println("<<< Releasing concurrency lock");
+ }
+ }
+}
+___________________________
+
+<bind pointcut="execution(protected void $instanceof{Transaction}->execute())">
+ <before name="beforeAdvice" aspect="MutexAspect"/>
+ <after name="afterAdvice" aspect="MutexAspect"/>
+</bind>
+</pre>
+</p><p>
+</p><p>
+But after advices are not assured to be executed always. If an exception is thrown
+during a transaction execution, the after advice will not be invoked, impeding the
+lock from being released, and locking the other threads. To avoid that situation, we
+should replace the after advice by a finally advice. Differently from the first, the
+finally advice will be executed always, avoiding a deadlock caused by an exception in
+one thread. Replacing the after advice in the example above is simple:
+</p><p>
+<pre>
+public class MutexAspect
+{
+ private Object lock = new Object();
+ private boolean locked = false;
+
+ public void beforeAdvice(@JoinPoint JoinPointInfo joinPoint)
+ {
+ synchronized(lock)
+ {
+ while (locked)
+ {
+ try
+ {
+ lock.wait();
+ }
+ catch(InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ return;
+ }
+ }
+ locked = true;
+ System.out.println(">>> Retrieved concurrency lock");
+ }
+ }
+
+ public void finallyAdvice(@JoinPoint JoinPointInfo joinPoint)
+ {
+ synchronized(lock)
+ {
+ locked = false;
+ lock.notifyAll();
+ System.out.println("<<< Releasing concurrency lock");
+ }
+ }
+}
+___________________________
+
+<bind pointcut="execution(protected void $instanceof{Transaction}->execute())">
+ <before name="beforeAdvice" aspect="MutexAspect"/>
+ <finally name="finallyAdvice" aspect="MutexAspect"/>
+</bind>
+
+</pre>
+</p><p>
+To illustrate the finally mechanism, we changed slightly the bank application, by
+throwing an exception when a transaction results in an negative balance.
+</p><p>
+</p><p>
+<h3> @Return and @Thrown Annotated-Paramaters</h3>
+
+</p><p>
+In the same way as other advices, finally advices can receive annotated-parameters.
+The semantics of those parameters has been explained in the
+<a href="../annotated-parameters/annotated-parameters.html">annotated-parameters</a> and
+<a href="../after-throwing/after-throwing.html">after-throwing</a> examples.
+</p><p>
+Besides everything we have seen, there are some subtleties regarding @Return and
+ at Thrown. Firstly, if a finally advice that receives a @Thrown parameter intercepts a
+joinpoint that returns normally, without errors, this parameter value will be
+<tt>null</tt>. An example of this follows:
+</p><p>
+<pre>
+public class FinallyAspect
+{
+ public void finallyAdvice1(@Thrown Throwable thrownException)
+ {
+ System.out.println(">>> finallyAdvice1 Exception has been thrown: " + (thrownException != null));
+ }
+}
+___________________________
+
+<bind pointcut="execution(private Account Bank->getAccount(java.lang.String))">
+ <finally name="finallyAdvice1" aspect="FinallyAspect"/>
+</bind>
+</pre>
+</p><p>
+</p><p>
+The finally advice above intercepts <tt>Bank.getAccount(String)</tt> method, that
+throws a <tt>NoSuchAccountException</tt> if the account name is invalid. It prints a
+message telling whether <tt>Bank.getAccount(String)</tt> threw an exception, which
+happened only if <tt>thrownException</tt> is not null.
+</p><p>
+A second consideration we need to make is that, if a finally advice receives a
+ at Return parameter, the use of @Thrown is compulsory. This is so because the
+ at Thrown parameter indicates the validity of the @Return parameter. This way, if the
+joinpoint being intercepted returns normally, @Thrown parameter value will be <tt>null</tt>
+and the @Return parameter will contain the joinpoint return value, as expected. If
+the joinpoint throws an exception, @Thrown parameter will contain the exception and
+the @Return value will invalid.
+</p><p>
+The following advice also intercepts <tt>Bank.getAccount(String)</tt> method execution,
+but this time it prints the result if no exception has been thrown.
+</p><p>
+<pre>
+public class FinallyAspect
+{
+ public void finallyAdvice2(@Return Account account,
+ @Thrown Throwable thrownException, @Arg String queriedName)
+ {
+ if (thrownException == null)
+ {
+ System.out.println(">>> finallyAdvice2 Account retrieved: " + account);
+ }
+ else
+ {
+ System.out.println(">>> finallyAdvice2 Account '" + queriedName +
+ "' not found");
+ }
+ }
+}
+___________________________
+
+<bind pointcut="execution(private Account Bank->getAccount(java.lang.String))">
+ <finally name="finallyAdvice2" aspect="FinallyAspect"/>
+</bind>
+</pre>
+</p><p>
+<h3>Running</h3>
+
+</p><p>
+<b>THIS EXAMPLE REQUIRES JDK 1.5!!</b> To compile and run:
+<pre>
+ $ ant
+</pre>
+It will javac the files and then run the AOPC precompiler to manipulate the bytecode, then finally run the example. The output should be similar to this:
+<pre>
+run:
+ [java] SETUP
+ [java] =====
+ [java] Creating account 'A' with initial balance of $30.0
+ [java] Creating account 'B' with initial balance of $50.0
+ [java] Creating account 'C' with initial balance of $0.0
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: A: US$ 30,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: A: US$ 30,00
+ [java] >>> finallyAdvice1 Exception has been thrown: true
+ [java] >>> finallyAdvice2 Account 'D' not found
+ [java] ERROR invalid transaction: Account named 'D' does not exist.
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: B: US$ 50,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: B: US$ 50,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: C: US$ 0,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: C: US$ 0,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: A: US$ 30,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: C: US$ 0,00
+ [java] >>> finallyAdvice1 Exception has been thrown: false
+ [java] >>> finallyAdvice2 Account retrieved: B: US$ 50,00
+
+ [java] TRANSACTIONS
+ [java] ============
+ [java] >>> Retrieved concurrency lock
+ [java] Withdrawing US$ 10,00 from account A
+ [java] <<< Releasing concurrency lock
+ [java] ---
+ [java] >>> Retrieved concurrency lock
+ [java] Transfering US$ 100,00 from account B to account C
+ [java] <<< Releasing concurrency lock
+ [java] ERROR can't perform operation because it results in: negative balance not allowed -US$ 100,00
+ [java] ---
+ [java] >>> Retrieved concurrency lock
+ [java] Depositing US$ 50,00 to account A
+ [java] <<< Releasing concurrency lock
+ [java] ---
+ [java] >>> Retrieved concurrency lock
+ [java] Transfering US$ 89,11 from account C to account A
+ [java] <<< Releasing concurrency lock
+ [java] ERROR can't perform operation because it results in: negative balance not allowed -US$ 89,11
+ [java] ---
+ [java] >>> Retrieved concurrency lock
+ [java] Depositing US$ 51,00 to account B
+ [java] <<< Releasing concurrency lock
+ [java] ---
+ [java] >>> Retrieved concurrency lock
+ [java] Withdrawing US$ 0,11 from account C
+ [java] <<< Releasing concurrency lock
+ [java] ERROR can't perform operation because it results in: negative balance not allowed -US$ 0,11
+ [java] ---
+ [java] >>> Retrieved concurrency lock
+ [java] Withdrawing US$ 5,00 from account B
+ [java] <<< Releasing concurrency lock
+ [java] ---
+
+ [java] FINAL BALANCE
+ [java] ===== =======
+ [java] A: US$ 70,00
+ [java] C: US$ 0,00
+ [java] B: US$ 96,00
+
+
+</pre>
+</p><p>
+As before, you can add accounts and transactions to this example application by editing the
+<tt>input.txt</tt> file.
+</p>
+</body>
+</html>
Added: projects/aop/trunk/aop/docs/examples/finally/input.txt
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/input.txt (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/input.txt 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,13 @@
+A $30.00
+B $50.00
+C $0.00
+
+A +$50.00
+A -$10.00
+D +$1.00
+B -$5.00
+B->C $100.00
+C->A $89.11
+C -$0.11
+B +$51.00
+
Added: projects/aop/trunk/aop/docs/examples/finally/jboss-aop.xml
===================================================================
--- projects/aop/trunk/aop/docs/examples/finally/jboss-aop.xml (rev 0)
+++ projects/aop/trunk/aop/docs/examples/finally/jboss-aop.xml 2007-05-08 06:10:55 UTC (rev 62854)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<aop>
+
+ <aspect class="MutexAspect" scope="PER_VM"/>
+
+ <bind pointcut="execution(protected void $instanceof{Transaction}->execute())">
+ <before name="beforeAdvice" aspect="MutexAspect"/>
+ <finally name="finallyAdvice" aspect="MutexAspect"/>
+ </bind>
+
+ <aspect class="FinallyAspect" scope="PER_VM"/>
+
+ <bind pointcut="execution(private Account Bank->getAccount(java.lang.String))">
+ <finally name="finallyAdvice1" aspect="FinallyAspect"/>
+ <finally name="finallyAdvice2" aspect="FinallyAspect"/>
+ </bind>
+
+</aop>
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list