[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 &lt;return-value&gt; &lt;any-method-name&gt;(@&lt;Annotation&gt; &lt;any type&gt; arg0, @&lt;Annotation&gt; &lt;any type&gt; arg1, ... , @&lt;Annotation&gt; &lt;any type&gt; argN) throws &lt;Exception1&gt;,&lt;Exception2&gt;,...,&lt;ExceptionN&gt;
+</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>
+&lt;bind pointcut="execution(* POJO-&gt;*(..))"&gt;
+      &lt;throwing name="finallyAdvice" aspect="Aspect"/&gt;
+&lt;/bind&gt;
+</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("&gt;&gt;&gt; Retrieved concurrency lock");
+      }
+   }
+   
+   public void afterAdvice(@JoinPoint Joinpoint joinPoint)
+   {
+      synchronized(lock)
+      {
+         locked = false;
+         lock.notify();
+         System.out.println("&lt;&lt;&lt; Releasing concurrency lock");
+      }
+   }
+}
+___________________________
+
+&lt;bind pointcut="execution(protected void $instanceof{Transaction}-&gt;execute())"&gt;
+   &lt;before name="beforeAdvice" aspect="MutexAspect"/&gt;
+   &lt;after name="afterAdvice" aspect="MutexAspect"/&gt;
+&lt;/bind&gt;
+</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("&gt;&gt;&gt; Retrieved concurrency lock");
+      }
+   }
+   
+   public void finallyAdvice(@JoinPoint JoinPointInfo joinPoint)
+   {
+      synchronized(lock)
+      {
+         locked = false;
+         lock.notifyAll();
+         System.out.println("&lt;&lt;&lt; Releasing concurrency lock");
+      }
+   }
+}
+___________________________
+
+&lt;bind pointcut="execution(protected void $instanceof{Transaction}-&gt;execute())"&gt;
+   &lt;before name="beforeAdvice" aspect="MutexAspect"/&gt;
+   &lt;finally name="finallyAdvice" aspect="MutexAspect"/&gt;
+&lt;/bind&gt;
+
+</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("&gt;&gt;&gt; finallyAdvice1 Exception has been thrown: " + (thrownException != null));
+   }
+}
+___________________________
+
+&lt;bind pointcut="execution(private Account Bank-&gt;getAccount(java.lang.String))"&gt;
+   &lt;finally name="finallyAdvice1" aspect="FinallyAspect"/&gt;
+&lt;/bind&gt;
+</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("&gt;&gt;&gt; finallyAdvice2 Account retrieved: " + account);
+      }
+      else
+      {
+         System.out.println("&gt;&gt;&gt; finallyAdvice2 Account '" + queriedName +
+               "' not found");
+      }
+   }
+}
+___________________________
+
+&lt;bind pointcut="execution(private Account Bank-&gt;getAccount(java.lang.String))"&gt;
+   &lt;finally name="finallyAdvice2" aspect="FinallyAspect"/&gt;
+&lt;/bind&gt;
+</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] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: A: US$ 30,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: A: US$ 30,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: true
+     [java] &gt;&gt;&gt; finallyAdvice2 Account 'D' not found
+     [java] ERROR invalid transaction: Account named 'D' does not exist.
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: B: US$ 50,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: B: US$ 50,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: C: US$ 0,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: C: US$ 0,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: A: US$ 30,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: C: US$ 0,00
+     [java] &gt;&gt;&gt; finallyAdvice1 Exception has been thrown: false
+     [java] &gt;&gt;&gt; finallyAdvice2 Account retrieved: B: US$ 50,00
+
+     [java] TRANSACTIONS
+     [java] ============
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Withdrawing US$ 10,00 from account A
+     [java] &lt;&lt;&lt; Releasing concurrency lock
+     [java] ---
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Transfering US$ 100,00 from account B to account C
+     [java] &lt;&lt;&lt; Releasing concurrency lock
+     [java] ERROR can't perform operation because it results in: negative balance not allowed -US$ 100,00
+     [java] ---
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Depositing US$ 50,00 to account A
+     [java] &lt;&lt;&lt; Releasing concurrency lock
+     [java] ---
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Transfering US$ 89,11 from account C to account A
+     [java] &lt;&lt;&lt; Releasing concurrency lock
+     [java] ERROR can't perform operation because it results in: negative balance not allowed -US$ 89,11
+     [java] ---
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Depositing US$ 51,00 to account B
+     [java] &lt;&lt;&lt; Releasing concurrency lock
+     [java] ---
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Withdrawing US$ 0,11 from account C
+     [java] &lt;&lt;&lt; Releasing concurrency lock
+     [java] ERROR can't perform operation because it results in: negative balance not allowed -US$ 0,11
+     [java] ---
+     [java] &gt;&gt;&gt; Retrieved concurrency lock
+     [java] Withdrawing US$ 5,00 from account B
+     [java] &lt;&lt;&lt; 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