You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by ka...@apache.org on 2010/02/02 13:53:47 UTC
svn commit: r905614 - in /incubator/shiro/trunk/samples/aspectj: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/shiro/ src/main/java/org/apache/shiro/sample/
src/main/java/org/apache/shiro/sample/...
Author: kaosko
Date: Tue Feb 2 12:53:45 2010
New Revision: 905614
URL: http://svn.apache.org/viewvc?rev=905614&view=rev
Log:
Add contributed aspectj sample (from SHIRO-129) after Mavenizing it and minor clean-up
Added:
incubator/shiro/trunk/samples/aspectj/ (with props)
incubator/shiro/trunk/samples/aspectj/pom.xml
incubator/shiro/trunk/samples/aspectj/src/
incubator/shiro/trunk/samples/aspectj/src/main/
incubator/shiro/trunk/samples/aspectj/src/main/java/
incubator/shiro/trunk/samples/aspectj/src/main/java/org/
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/Account.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountNotFoundException.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountTransaction.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServerRunner.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankService.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServiceException.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/InactiveAccountException.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/NotEnoughFundsException.java
incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/SecureBankService.java
incubator/shiro/trunk/samples/aspectj/src/test/
incubator/shiro/trunk/samples/aspectj/src/test/java/
incubator/shiro/trunk/samples/aspectj/src/test/java/org/
incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/
incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/
incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/
incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/bank/
incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/bank/SecureBankServiceTest.java
incubator/shiro/trunk/samples/aspectj/src/test/resources/
incubator/shiro/trunk/samples/aspectj/src/test/resources/META-INF/
incubator/shiro/trunk/samples/aspectj/src/test/resources/META-INF/aop.xml
incubator/shiro/trunk/samples/aspectj/src/test/resources/log4j.properties
incubator/shiro/trunk/samples/aspectj/src/test/resources/shiroBankServiceTest.ini
Propchange: incubator/shiro/trunk/samples/aspectj/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Feb 2 12:53:45 2010
@@ -0,0 +1,3 @@
+.classpath
+.project
+.settings
Added: incubator/shiro/trunk/samples/aspectj/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/pom.xml?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/pom.xml (added)
+++ incubator/shiro/trunk/samples/aspectj/pom.xml Tue Feb 2 12:53:45 2010
@@ -0,0 +1,86 @@
+<?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.
+ -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.shiro.samples</groupId>
+ <artifactId>shiro-samples</artifactId>
+ <version>1.0-incubating-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>samples-aspectj</artifactId>
+ <name>Apache Shiro :: Samples :: AspectJ</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <version>1.3</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ <showWeaveInfo>true</showWeaveInfo>
+ <aspectLibraries>
+ <aspectLibrary>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-aspectj</artifactId>
+ </aspectLibrary>
+ </aspectLibraries>
+ </configuration>
+ <executions>
+ <execution>
+ <id>aspectj-compile</id>
+ <goals>
+ <goal>test-compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-aspectj</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.15</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.5.8</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/Account.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/Account.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/Account.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/Account.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,169 @@
+package org.apache.shiro.sample.bank;
+
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.shiro.sample.bank.AccountTransaction.TransactionType;
+
+
+public class Account {
+
+ private static long _SEQUENCE;
+
+ private long _id;
+
+ private String _ownerName;
+
+ private boolean _isActive;
+
+ private double _balance;
+
+ private List<AccountTransaction> _transactions;
+
+ private String _createdBy;
+
+ private Date _creationDate;
+
+ public Account(String anOwnerName) {
+ _id = ++_SEQUENCE;
+ _ownerName = anOwnerName;
+ _isActive = true;
+ _balance = 0.0d;
+ _transactions = new ArrayList<AccountTransaction>();
+ _createdBy = "unknown";
+ _creationDate = new Date();
+ }
+
+ /**
+ * Returns the id attribute.
+ *
+ * @return The id value.
+ */
+ public long getId() {
+ return _id;
+ }
+
+ /**
+ * Returns the ownerName attribute.
+ *
+ * @return The ownerName value.
+ */
+ public String getOwnerName() {
+ return _ownerName;
+ }
+
+ /**
+ * Returns the isActive attribute.
+ *
+ * @return The isActive value.
+ */
+ public boolean isActive() {
+ return _isActive;
+ }
+
+ /**
+ * Changes the value of the attributes isActive.
+ *
+ * @param aIsActive The new value of the isActive attribute.
+ */
+ public void setActive(boolean aIsActive) {
+ _isActive = aIsActive;
+ }
+
+ /**
+ * Changes the value of the attributes ownerName.
+ *
+ * @param aOwnerName The new value of the ownerName attribute.
+ */
+ public void setOwnerName(String aOwnerName) {
+ _ownerName = aOwnerName;
+ }
+
+ /**
+ * Returns the balance attribute.
+ *
+ * @return The balance value.
+ */
+ public double getBalance() {
+ return _balance;
+ }
+
+ /**
+ * Returns the transactions attribute.
+ *
+ * @return The transactions value.
+ */
+ public List<AccountTransaction> getTransactions() {
+ return _transactions;
+ }
+
+ protected void applyTransaction(AccountTransaction aTransaction) throws NotEnoughFundsException, InactiveAccountException {
+ if (!_isActive) {
+ throw new InactiveAccountException("Unable to apply " + aTransaction.getType() + " of amount " + aTransaction.getAmount() + " to account " + _id);
+ }
+
+ synchronized (_transactions) {
+ if (TransactionType.DEPOSIT == aTransaction.getType()) {
+ _transactions.add(aTransaction);
+ _balance += aTransaction.getAmount();
+
+ } else if (TransactionType.WITHDRAWAL == aTransaction.getType()) {
+ if (_balance < aTransaction.getAmount()) {
+ throw new NotEnoughFundsException("Unable to withdraw " + aTransaction.getAmount() + "$ from account " + _id + " - current balance is " + _balance);
+ }
+ _transactions.add(aTransaction);
+ _balance -= aTransaction.getAmount();
+
+ } else {
+ throw new IllegalArgumentException("The transaction passed in has an invalid type: " + aTransaction.getType());
+ }
+ }
+ }
+
+ /**
+ * Changes the value of the attributes createdBy.
+ *
+ * @param aCreatedBy The new value of the createdBy attribute.
+ */
+ protected void setCreatedBy(String aCreatedBy) {
+ _createdBy = aCreatedBy;
+ }
+
+ /**
+ * Returns the createdBy attribute.
+ *
+ * @return The createdBy value.
+ */
+ public String getCreatedBy() {
+ return _createdBy;
+ }
+
+ /**
+ * Returns the creationDate attribute.
+ *
+ * @return The creationDate value.
+ */
+ public Date getCreationDate() {
+ return _creationDate;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
+ append("id", _id).
+ append("ownerName", _ownerName).
+ append("isActive", _isActive).
+ append("balance", _balance).
+ append("tx.count", _transactions.size()).
+ append("createdBy", _createdBy).
+ append("creationDate", new Timestamp(_creationDate.getTime())).
+ toString();
+ }
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountNotFoundException.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountNotFoundException.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountNotFoundException.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountNotFoundException.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,10 @@
+package org.apache.shiro.sample.bank;
+
+
+public class AccountNotFoundException extends BankServiceException {
+
+ public AccountNotFoundException(String aMessage) {
+ super(aMessage);
+ }
+
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountTransaction.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountTransaction.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountTransaction.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/AccountTransaction.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,126 @@
+package org.apache.shiro.sample.bank;
+
+
+import java.sql.Timestamp;
+import java.util.Date;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+public class AccountTransaction {
+
+ private static long _SEQUENCE;
+
+ public enum TransactionType {
+ DEPOSIT,
+ WITHDRAWAL;
+ }
+
+ private long _id;
+
+ private TransactionType _type;
+
+ private long _accountId;
+
+ private double _amount;
+
+ private String _createdBy;
+ private Date _creationDate;
+
+ public static AccountTransaction createDepositTx(long anAccountId, double anAmount) {
+ AccountTransaction tx = new AccountTransaction(TransactionType.DEPOSIT, anAccountId, anAmount);
+ return tx;
+ }
+
+ public static AccountTransaction createWithdrawalTx(long anAccountId, double anAmount) {
+ AccountTransaction tx = new AccountTransaction(TransactionType.WITHDRAWAL, anAccountId, anAmount);
+ return tx;
+ }
+
+ private AccountTransaction(TransactionType aType, long anAccountId, double anAmount) {
+ _id = ++_SEQUENCE;
+ _type = aType;
+ _accountId = anAccountId;
+ _amount = anAmount;
+ _createdBy = "unknown";
+ _creationDate = new Date();
+ }
+
+ /**
+ * Returns the id attribute.
+ *
+ * @return The id value.
+ */
+ public long getId() {
+ return _id;
+ }
+
+ /**
+ * Returns the type attribute.
+ *
+ * @return The type value.
+ */
+ public TransactionType getType() {
+ return _type;
+ }
+
+ /**
+ * Returns the accountId attribute.
+ *
+ * @return The accountId value.
+ */
+ public long getAccountId() {
+ return _accountId;
+ }
+
+ /**
+ * Returns the amount attribute.
+ *
+ * @return The amount value.
+ */
+ public double getAmount() {
+ return _amount;
+ }
+
+ /**
+ * Changes the value of the attributes createdBy.
+ *
+ * @param aCreatedBy The new value of the createdBy attribute.
+ */
+ protected void setCreatedBy(String aCreatedBy) {
+ _createdBy = aCreatedBy;
+ }
+
+ /**
+ * Returns the createdBy attribute.
+ *
+ * @return The createdBy value.
+ */
+ public String getCreatedBy() {
+ return _createdBy;
+ }
+
+ /**
+ * Returns the creationDate attribute.
+ *
+ * @return The creationDate value.
+ */
+ public Date getCreationDate() {
+ return _creationDate;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
+ append("id", _id).
+ append("type", _type).
+ append("accountId", _accountId).
+ append("amount", _amount).
+ append("createdBy", _createdBy).
+ append("creationDate", new Timestamp(_creationDate.getTime())).
+ toString();
+ }
+
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServerRunner.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServerRunner.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServerRunner.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServerRunner.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,41 @@
+package org.apache.shiro.sample.bank;
+
+
+public class BankServerRunner {
+
+ private SecureBankService _bankService;
+
+ public synchronized void start() throws Exception {
+ if (_bankService == null) {
+ _bankService = new SecureBankService();
+ _bankService.start();
+ }
+ }
+
+ public synchronized void stop() {
+ if (_bankService != null) {
+ try {
+ _bankService.dispose();
+ } finally {
+ _bankService = null;
+ }
+ }
+ }
+
+ public BankService getBankService() {
+ return _bankService;
+ }
+
+ public static void main(String[] args) {
+ try {
+ BankServerRunner server = new BankServerRunner();
+ server.start();
+
+ server.stop();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankService.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankService.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankService.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankService.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,62 @@
+package org.apache.shiro.sample.bank;
+
+
+import java.util.Date;
+
+public interface BankService {
+
+ public long[] searchAccountIdsByOwner(String anOwnerName);
+
+ public long createNewAccount(String anOwnerName);
+
+ public double getBalanceOf(long anAccountId) throws AccountNotFoundException;
+
+ public String getOwnerOf(long anAccountId) throws AccountNotFoundException;
+
+ public double depositInto(long anAccountId, double anAmount) throws AccountNotFoundException, InactiveAccountException;
+
+ public double withdrawFrom(long anAccountId, double anAmount) throws AccountNotFoundException, NotEnoughFundsException, InactiveAccountException;
+
+ public TxLog[] getTxHistoryFor(long anAccountId) throws AccountNotFoundException;
+
+ public double closeAccount(long anAccountId) throws AccountNotFoundException, InactiveAccountException;
+
+ public boolean isAccountActive(long anAccountId) throws AccountNotFoundException;
+
+ public static class TxLog {
+ private Date _creationDate;
+ private double _amount;
+ private String _madeBy;
+ public TxLog(Date aCreationDate, double aAmount, String aMadeBy) {
+ super();
+ _creationDate = aCreationDate;
+ _amount = aAmount;
+ _madeBy = aMadeBy;
+ }
+ /**
+ * Returns the creationDate attribute.
+ *
+ * @return The creationDate value.
+ */
+ public Date getCreationDate() {
+ return _creationDate;
+ }
+ /**
+ * Returns the amount attribute.
+ *
+ * @return The amount value.
+ */
+ public double getAmount() {
+ return _amount;
+ }
+ /**
+ * Returns the madeBy attribute.
+ *
+ * @return The madeBy value.
+ */
+ public String getMadeBy() {
+ return _madeBy;
+ }
+ }
+
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServiceException.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServiceException.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServiceException.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/BankServiceException.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,14 @@
+package org.apache.shiro.sample.bank;
+
+
+public class BankServiceException extends Exception {
+
+ public BankServiceException(String aMessage) {
+ super(aMessage);
+ }
+
+ public BankServiceException(String aMessage, Throwable aCause) {
+ super(aMessage, aCause);
+ }
+
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/InactiveAccountException.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/InactiveAccountException.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/InactiveAccountException.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/InactiveAccountException.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,10 @@
+package org.apache.shiro.sample.bank;
+
+
+public class InactiveAccountException extends BankServiceException {
+
+ public InactiveAccountException(String aMessage) {
+ super(aMessage);
+ }
+
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/NotEnoughFundsException.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/NotEnoughFundsException.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/NotEnoughFundsException.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/NotEnoughFundsException.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,10 @@
+package org.apache.shiro.sample.bank;
+
+
+public class NotEnoughFundsException extends BankServiceException {
+
+ public NotEnoughFundsException(String aMessage) {
+ super(aMessage);
+ }
+
+}
Added: incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/SecureBankService.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/SecureBankService.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/SecureBankService.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/main/java/org/apache/shiro/sample/bank/SecureBankService.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,279 @@
+package org.apache.shiro.sample.bank;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+
+import org.apache.shiro.sample.bank.AccountTransaction.TransactionType;
+import org.apache.shiro.subject.Subject;
+
+public class SecureBankService implements BankService {
+
+ private Logger _logger;
+ private boolean _isRunning;
+ private List<Account> _accounts;
+ private Map<Long,Account> _accountsById;
+
+ /**
+ * Creates a new {@link SecureBankService} instance.
+ */
+ public SecureBankService() {
+ _logger = Logger.getLogger(SecureBankService.class);
+ _accounts = new ArrayList<Account>();
+ _accountsById = new HashMap<Long, Account>();
+ }
+
+ /**
+ * Starts this service
+ */
+ public void start() throws Exception {
+ _isRunning = true;
+ _logger.info("Bank service started");
+ }
+
+ /**
+ * Stop this service
+ */
+ public void dispose() {
+ _logger.info("Stopping bank service...");
+ _isRunning = false;
+
+ synchronized (_accounts) {
+ _accountsById.clear();
+ _accounts.clear();
+ }
+
+ _logger.info("Bank service stopped");
+ }
+
+ /**
+ * Internal utility method that validate the internal state of this service.
+ */
+ protected void assertServiceState() {
+ if (!_isRunning) {
+ throw new IllegalStateException("This bank service is not running");
+ }
+ }
+
+ public int getAccountCount() {
+ return _accounts.size();
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#createNewAccount(java.lang.String)
+ */
+ @RequiresPermissions("bank:createAccount")
+ public long createNewAccount(String anOwnerName) {
+ assertServiceState();
+ _logger.info("Creating new account for " + anOwnerName);
+
+ synchronized (_accounts) {
+ Account account = new Account(anOwnerName);
+ account.setCreatedBy(getCurrentUsername());
+ _accounts.add(account);
+ _accountsById.put(account.getId(), account);
+
+ _logger.debug("Created new account: " + account);
+ return account.getId();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#searchAccountIdsByOwner(java.lang.String)
+ */
+ public long[] searchAccountIdsByOwner(String anOwnerName) {
+ assertServiceState();
+ _logger.info("Searching existing accounts for " + anOwnerName);
+
+ ArrayList<Account> matchAccounts = new ArrayList<Account>();
+ synchronized (_accounts) {
+ for (Account a: _accounts) {
+ if (a.getOwnerName().toLowerCase().contains(anOwnerName.toLowerCase())) {
+ matchAccounts.add(a);
+ }
+ }
+ }
+
+ long[] accountIds = new long[matchAccounts.size()];
+ int index = 0;
+ for(Account a: matchAccounts) {
+ accountIds[index++] = a.getId();
+ }
+
+ _logger.debug("Found " + accountIds.length + " account(s) matching the name " + anOwnerName);
+ return accountIds;
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#getOwnerOf(long)
+ */
+ @RequiresPermissions("bank:readAccount")
+ public String getOwnerOf(long anAccountId) throws AccountNotFoundException {
+ assertServiceState();
+ _logger.info("Getting owner of account " + anAccountId);
+
+ Account a = safellyRetrieveAccountForId(anAccountId);
+ return a.getOwnerName();
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#getBalanceOf(long)
+ */
+ @RequiresPermissions("bank:readAccount")
+ public double getBalanceOf(long anAccountId) throws AccountNotFoundException {
+ assertServiceState();
+ _logger.info("Getting balance of account " + anAccountId);
+
+ Account a = safellyRetrieveAccountForId(anAccountId);
+ return a.getBalance();
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#depositInto(long, double)
+ */
+ @RequiresPermissions("bank:operateAccount")
+ public double depositInto(long anAccountId, double anAmount) throws AccountNotFoundException, InactiveAccountException {
+ assertServiceState();
+ _logger.info("Making deposit of " + anAmount + " into account " + anAccountId);
+
+ try {
+ Account a = safellyRetrieveAccountForId(anAccountId);
+ AccountTransaction tx = AccountTransaction.createDepositTx(anAccountId, anAmount);
+ tx.setCreatedBy(getCurrentUsername());
+ _logger.debug("Created a new transaction " + tx);
+
+ a.applyTransaction(tx);
+ _logger.debug("New balance of account " + a.getId() + " after deposit is " + a.getBalance());
+
+ return a.getBalance();
+
+ } catch (NotEnoughFundsException nefe) {
+ throw new IllegalStateException("Should never happen", nefe);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#withdrawFrom(long, double)
+ */
+ @RequiresPermissions("bank:operateAccount")
+ public double withdrawFrom(long anAccountId, double anAmount) throws AccountNotFoundException, NotEnoughFundsException, InactiveAccountException {
+ assertServiceState();
+ _logger.info("Making withdrawal of " + anAmount + " from account " + anAccountId);
+
+ Account a = safellyRetrieveAccountForId(anAccountId);
+ AccountTransaction tx = AccountTransaction.createWithdrawalTx(anAccountId, anAmount);
+ tx.setCreatedBy(getCurrentUsername());
+ _logger.debug("Created a new transaction " + tx);
+
+ a.applyTransaction(tx);
+ _logger.debug("New balance of account " + a.getId() + " after withdrawal is " + a.getBalance());
+
+ return a.getBalance();
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#getTxHistoryFor(long)
+ */
+ @RequiresPermissions("bank:readAccount")
+ public TxLog[] getTxHistoryFor(long anAccountId) throws AccountNotFoundException {
+ assertServiceState();
+ _logger.info("Getting transactions of account " + anAccountId);
+
+ Account a = safellyRetrieveAccountForId(anAccountId);
+
+ TxLog[] txs = new TxLog[a.getTransactions().size()];
+ int index = 0;
+ for (AccountTransaction tx: a.getTransactions()) {
+ _logger.debug("Retrieved transaction " + tx);
+
+ if (TransactionType.DEPOSIT == tx.getType()) {
+ txs[index++] = new TxLog(tx.getCreationDate(), tx.getAmount(), tx.getCreatedBy());
+ } else {
+ txs[index++] = new TxLog(tx.getCreationDate(), -1.0d * tx.getAmount(), tx.getCreatedBy());
+ }
+ }
+
+ return txs;
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#closeAccount(long)
+ */
+ @RequiresPermissions("bank:closeAccount")
+ public double closeAccount(long anAccountId) throws AccountNotFoundException, InactiveAccountException {
+ assertServiceState();
+ _logger.info("Closing account " + anAccountId);
+
+ Account a = safellyRetrieveAccountForId(anAccountId);
+ if (!a.isActive()) {
+ throw new InactiveAccountException("The account " + anAccountId + " is already closed");
+ }
+
+ try {
+ AccountTransaction tx = AccountTransaction.createWithdrawalTx(a.getId(), a.getBalance());
+ tx.setCreatedBy(getCurrentUsername());
+ _logger.debug("Created a new transaction " + tx);
+ a.applyTransaction(tx);
+ a.setActive(false);
+
+ _logger.debug("Account " + a.getId() + " is now closed and an amount of " + tx.getAmount() + " is given to the owner");
+ return tx.getAmount();
+
+ } catch (NotEnoughFundsException nefe) {
+ throw new IllegalStateException("Should never happen", nefe);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.connectif.trilogy.root.security.BankService#isAccountActive(long)
+ */
+ @RequiresPermissions("bank:readAccount")
+ public boolean isAccountActive(long anAccountId) throws AccountNotFoundException {
+ assertServiceState();
+ _logger.info("Getting active status of account " + anAccountId);
+
+ Account a = safellyRetrieveAccountForId(anAccountId);
+ return a.isActive();
+ }
+
+
+ /**
+ * Internal method that safelly (concurrency-wise) retrieves an account from the id passed in.
+ *
+ * @param anAccountId The identifier of the account to retrieve.
+ * @return The account instance retrieved.
+ * @throws AccountNotFoundException If no account is found for the provided identifier.
+ */
+ protected Account safellyRetrieveAccountForId(long anAccountId) throws AccountNotFoundException {
+ Account account = null;
+ synchronized (_accounts) {
+ account = _accountsById.get(anAccountId);
+ }
+
+ if (account == null) {
+ throw new AccountNotFoundException("No account found for the id " + anAccountId);
+ }
+
+ _logger.info("Retrieved account " + account);
+ return account;
+ }
+
+ /**
+ * Internal utility method to retrieve the username of the current authenticated user.
+ *
+ * @return The name.
+ */
+ protected String getCurrentUsername() {
+ Subject subject = SecurityUtils.getSubject();
+ if (subject == null || subject.getPrincipal() == null || !subject.isAuthenticated()) {
+ throw new IllegalStateException("Unable to retrieve the current authenticated subject");
+ }
+ return SecurityUtils.getSubject().getPrincipal().toString();
+ }
+}
Added: incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/bank/SecureBankServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/bank/SecureBankServiceTest.java?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/bank/SecureBankServiceTest.java (added)
+++ incubator/shiro/trunk/samples/aspectj/src/test/java/org/apache/shiro/sample/bank/SecureBankServiceTest.java Tue Feb 2 12:53:45 2010
@@ -0,0 +1,227 @@
+package org.apache.shiro.sample.bank;
+
+
+import junit.framework.Assert;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Logger;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.config.IniSecurityManagerFactory;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.Factory;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SecureBankServiceTest {
+
+ private static Logger logger;
+ private static SecureBankService service;
+ private static int testCounter;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ BasicConfigurator.resetConfiguration();
+ BasicConfigurator.configure();
+ logger = Logger.getLogger(SecureBankServiceTest.class.getSimpleName());
+
+ Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiroBankServiceTest.ini");
+ SecurityManager securityManager = factory.getInstance();
+ SecurityUtils.setSecurityManager(securityManager);
+
+ service = new SecureBankService();
+ service.start();
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ if (service != null) {
+ service.dispose();
+ }
+ }
+
+ private Subject _subject;
+
+ @Before
+ public void setUp() throws Exception {
+ logger.info("\n\n#########################\n### STARTING TEST CASE " + (++testCounter) + "\n");
+ Thread.sleep(50);
+ }
+
+ @After
+ public void tearDown() {
+ if (_subject != null) {
+ _subject.logout();
+ }
+ }
+
+ protected void logoutCurrentSubject() {
+ if (_subject != null) {
+ _subject.logout();
+ }
+ }
+
+ protected void loginAsUser() {
+ if (_subject == null) {
+ _subject = SecurityUtils.getSubject();
+ }
+
+ // use dan to run as a normal user (which cannot close an account)
+ _subject.login(new UsernamePasswordToken("dan", "123"));
+ }
+
+ protected void loginAsSuperviser() {
+ if (_subject == null) {
+ _subject = SecurityUtils.getSubject();
+ }
+
+ // use sally to run as a superviser (which cannot operate an account)
+ _subject.login(new UsernamePasswordToken("sally", "1234"));
+ }
+
+ @Test
+ public void testCreateAccount() throws Exception {
+ loginAsUser();
+ createAndValidateAccountFor("Bob Smith");
+ }
+
+ @Test
+ public void testDepositInto_singleTx() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Joe Smith");
+ makeDepositAndValidateAccount(accountId, 250.00d, "Joe Smith");
+ }
+
+ @Test
+ public void testDepositInto_multiTxs() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Everett Smith");
+ makeDepositAndValidateAccount(accountId, 50.00d, "Everett Smith");
+ makeDepositAndValidateAccount(accountId, 300.00d, "Everett Smith");
+ makeDepositAndValidateAccount(accountId, 85.00d, "Everett Smith");
+ assertAccount("Everett Smith", true, 435.00d, 3, accountId);
+ }
+
+ @Test(expected=NotEnoughFundsException.class)
+ public void testWithdrawFrom_emptyAccount() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Wally Smith");
+ service.withdrawFrom(accountId, 100.00d);
+ }
+
+ @Test(expected=NotEnoughFundsException.class)
+ public void testWithdrawFrom_notEnoughFunds() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Frank Smith");
+ makeDepositAndValidateAccount(accountId, 50.00d, "Frank Smith");
+ service.withdrawFrom(accountId, 100.00d);
+ }
+
+ @Test
+ public void testWithdrawFrom_singleTx() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Al Smith");
+ makeDepositAndValidateAccount(accountId, 500.00d, "Al Smith");
+ makeWithdrawalAndValidateAccount(accountId, 100.00d, "Al Smith");
+ assertAccount("Al Smith", true, 400.00d, 2, accountId);
+ }
+
+ @Test
+ public void testWithdrawFrom_manyTxs() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Zoe Smith");
+ makeDepositAndValidateAccount(accountId, 500.00d, "Zoe Smith");
+ makeWithdrawalAndValidateAccount(accountId, 100.00d, "Zoe Smith");
+ makeWithdrawalAndValidateAccount(accountId, 75.00d, "Zoe Smith");
+ makeWithdrawalAndValidateAccount(accountId, 125.00d, "Zoe Smith");
+ assertAccount("Zoe Smith", true, 200.00d, 4, accountId);
+ }
+
+ @Test
+ public void testWithdrawFrom_upToZero() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Zoe Smith");
+ makeDepositAndValidateAccount(accountId, 500.00d, "Zoe Smith");
+ makeWithdrawalAndValidateAccount(accountId, 500.00d, "Zoe Smith");
+ assertAccount("Zoe Smith", true, 0.00d, 2, accountId);
+ }
+
+ @Test
+ public void testCloseAccount_zeroBalance() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Chris Smith");
+
+ logoutCurrentSubject();
+ loginAsSuperviser();
+ double closingBalance = service.closeAccount(accountId);
+ Assert.assertEquals(0.00d, closingBalance);
+ assertAccount("Chris Smith", false, 0.00d, 1, accountId);
+ }
+
+ @Test
+ public void testCloseAccount_withBalance() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Gerry Smith");
+ makeDepositAndValidateAccount(accountId, 385.00d, "Gerry Smith");
+
+ logoutCurrentSubject();
+ loginAsSuperviser();
+ double closingBalance = service.closeAccount(accountId);
+ Assert.assertEquals(385.00d, closingBalance);
+ assertAccount("Gerry Smith", false, 0.00d, 2, accountId);
+ }
+
+ @Test(expected=InactiveAccountException.class)
+ public void testCloseAccount_alreadyClosed() throws Exception {
+ loginAsUser();
+ long accountId = createAndValidateAccountFor("Chris Smith");
+
+ logoutCurrentSubject();
+ loginAsSuperviser();
+ double closingBalance = service.closeAccount(accountId);
+ Assert.assertEquals(0.00d, closingBalance);
+ assertAccount("Chris Smith", false, 0.00d, 1, accountId);
+ service.closeAccount(accountId);
+ }
+
+
+
+
+ protected long createAndValidateAccountFor(String anOwner) throws Exception {
+ long createdId = service.createNewAccount(anOwner);
+ assertAccount(anOwner, true, 0.0d, 0, createdId);
+ return createdId;
+ }
+
+ protected double makeDepositAndValidateAccount(long anAccountId, double anAmount, String eOwnerName) throws Exception {
+ double previousBalance = service.getBalanceOf(anAccountId);
+ int previousTxCount = service.getTxHistoryFor(anAccountId).length;
+ double newBalance = service.depositInto(anAccountId, anAmount);
+ Assert.assertEquals(previousBalance+anAmount, newBalance);
+ assertAccount(eOwnerName, true, newBalance, 1+previousTxCount, anAccountId);
+ return newBalance;
+ }
+
+ protected double makeWithdrawalAndValidateAccount(long anAccountId, double anAmount, String eOwnerName) throws Exception {
+ double previousBalance = service.getBalanceOf(anAccountId);
+ int previousTxCount = service.getTxHistoryFor(anAccountId).length;
+ double newBalance = service.withdrawFrom(anAccountId, anAmount);
+ Assert.assertEquals(previousBalance-anAmount, newBalance);
+ assertAccount(eOwnerName, true, newBalance, 1+previousTxCount, anAccountId);
+ return newBalance;
+ }
+
+
+
+
+ public static void assertAccount(String eOwnerName, boolean eIsActive, double eBalance, int eTxLogCount, long actualAccountId) throws Exception {
+ Assert.assertEquals(eOwnerName, service.getOwnerOf(actualAccountId));
+ Assert.assertEquals(eIsActive, service.isAccountActive(actualAccountId));
+ Assert.assertEquals(eBalance, service.getBalanceOf(actualAccountId));
+ Assert.assertEquals(eTxLogCount, service.getTxHistoryFor(actualAccountId).length);
+ }
+}
Added: incubator/shiro/trunk/samples/aspectj/src/test/resources/META-INF/aop.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/test/resources/META-INF/aop.xml?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/test/resources/META-INF/aop.xml (added)
+++ incubator/shiro/trunk/samples/aspectj/src/test/resources/META-INF/aop.xml Tue Feb 2 12:53:45 2010
@@ -0,0 +1,14 @@
+<aspectj>
+
+ <aspects>
+ <!-- declare shiro aspects to the weaver -->
+ <aspect name="org.apache.shiro.aspectj.ShiroAnnotationAuthorizingAspect"/>
+ </aspects>
+
+ <weaver options="-verbose -showWeaveInfo">
+ <!-- Weave types that are within the org.apache.shiro.sample package
+ and all sub-packages. This limits the scope of the weaver and
+ reduces the overhead -->
+ <include within="org.apache.shiro.sample..*"/>
+ </weaver>
+</aspectj>
Added: incubator/shiro/trunk/samples/aspectj/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/test/resources/log4j.properties?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/test/resources/log4j.properties (added)
+++ incubator/shiro/trunk/samples/aspectj/src/test/resources/log4j.properties Tue Feb 2 12:53:45 2010
@@ -0,0 +1,10 @@
+log4j.rootCategory=info, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=[%p] %c{2} %m%n
+
+log4j.category.org.apache.shiro.aspectj=TRACE
\ No newline at end of file
Added: incubator/shiro/trunk/samples/aspectj/src/test/resources/shiroBankServiceTest.ini
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/aspectj/src/test/resources/shiroBankServiceTest.ini?rev=905614&view=auto
==============================================================================
--- incubator/shiro/trunk/samples/aspectj/src/test/resources/shiroBankServiceTest.ini (added)
+++ incubator/shiro/trunk/samples/aspectj/src/test/resources/shiroBankServiceTest.ini Tue Feb 2 12:53:45 2010
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+
+# -----------------------------------------------------------------------------
+# Users and their assigned roles
+#
+# Each line conforms to the format defined in the
+# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
+# -----------------------------------------------------------------------------
+[users]
+root = secret, admin
+sally = 1234, superviser
+dan = 123, user
+
+
+# -----------------------------------------------------------------------------
+# Roles with assigned permissions
+#
+# Each line conforms to the format defined in the
+# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
+# -----------------------------------------------------------------------------
+[roles]
+admin = bank:*
+superviser = bank:readAccount, bank:createAccount, bank:closeAccount
+user = bank:readAccount, bank:operateAccount, bank:createAccount