001: package org.gomba;
002:
003: import java.util.Map;
004:
005: import javax.servlet.ServletConfig;
006: import javax.servlet.ServletException;
007: import javax.servlet.http.HttpServlet;
008:
009: /**
010: * Base class for servlets that support RESTful transactions.
011: *
012: * <p>
013: * Context params:
014: * </p>
015: * <dl>
016: * <dt>org.gomba.transactionURI</dt>
017: * <dd>Expression that evaluates to a transaction identifier or to
018: * <code>null</code> if the current request is not bound to a transaction.
019: * This context-param is a shortcut to globally configure all
020: * <code>TransactorAbstractServlet</code>.
021: * </dd>
022: * </dl>
023: *
024: * <p>
025: * Init params:
026: * </p>
027: * <dl>
028: * <dt>transaction-uri</dt>
029: * <dd>Expression that evaluates to a transaction identifier or to
030: * <code>null</code> if the current request is not bound to a transaction.
031: * </dd>
032: * </dl>
033: *
034: * @author Flavio Tordini
035: * @version $Id: TransactorAbstractServlet.java,v 1.1 2004/11/26 17:52:58
036: * flaviotordini Exp $
037: */
038: public abstract class TransactorAbstractServlet extends HttpServlet {
039:
040: /**
041: * Name of the request attribute that holds a transaction generated by a
042: * servlet (i.e. MultiServlet).
043: */
044: protected final static String REQUEST_ATTRIBUTE_NAME_TRANSACTION = "org_gomba_transaction";
045:
046: protected final static String CONTEXT_PARAM_TRANSACTION_URI = "org.gomba.transactionURI";
047:
048: private final static String INIT_PARAM_TRANSACTION_URI = "transaction-uri";
049:
050: private Expression transactionUriExpression;
051:
052: /**
053: * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
054: */
055: public void init(ServletConfig config) throws ServletException {
056: super .init(config);
057:
058: // transaction uri expression
059: this .transactionUriExpression = getTransactionURIExpression(config);
060: }
061:
062: /**
063: * Get the configured expression for the transaction URI.
064: */
065: private static final Expression getTransactionURIExpression(
066: ServletConfig config) throws ServletException {
067:
068: final Expression transactionUriExpression;
069: String uriExpressionStr = config
070: .getInitParameter(INIT_PARAM_TRANSACTION_URI);
071: if (uriExpressionStr == null) {
072: uriExpressionStr = config.getServletContext()
073: .getInitParameter(CONTEXT_PARAM_TRANSACTION_URI);
074: }
075: if (uriExpressionStr == null) {
076: return null;
077: }
078: try {
079: transactionUriExpression = new Expression(uriExpressionStr);
080: } catch (Exception e) {
081: throw new ServletException("Error parsing "
082: + INIT_PARAM_TRANSACTION_URI, e);
083: }
084: return transactionUriExpression;
085: }
086:
087: /**
088: * Get the transaction URI for the current request, if any.
089: *
090: * @return A String representing the transaction URI or null, if none is
091: * available.
092: */
093: private final String getTransactionURI(
094: ParameterResolver parameterResolver)
095: throws ServletException {
096: Object obj;
097: try {
098: obj = this .transactionUriExpression
099: .replaceParameters(parameterResolver);
100: } catch (MissingParameterException e) {
101: return null;
102: } catch (Exception e) {
103: throw new ServletException(
104: "Error evaluating transaction URI expression.", e);
105: }
106:
107: return obj.toString();
108: }
109:
110: /**
111: * Subclasses may call this method to retrieve the current Transaction.
112: *
113: * @param parameterResolver
114: * A ParameterResolver resolver instance.
115: * @return A Transaction instance or null, if the current request is not
116: * part of a transaction.
117: */
118: protected final Transaction getTransaction(
119: ParameterResolver parameterResolver)
120: throws ServletException {
121:
122: // first check if the transaction has been put in the request scope by
123: // MultiServlet
124: Transaction transaction = (Transaction) parameterResolver
125: .getRequest().getAttribute(
126: REQUEST_ATTRIBUTE_NAME_TRANSACTION);
127: if (transaction != null) {
128: return transaction;
129: }
130:
131: if (this .transactionUriExpression == null) {
132: return null;
133: }
134: String transactionURI = getTransactionURI(parameterResolver);
135: if (transactionURI == null) {
136: return null;
137: }
138: Map transactions = (Map) getServletContext().getAttribute(
139: TransactionServlet.CONTEXT_ATTRIBUTE_NAME_TRANSACTIONS);
140: if (transactions == null) {
141: // throw new ServletException("Transactions map is missing.");
142: return null;
143: }
144: transaction = (Transaction) transactions.get(transactionURI);
145: if (transaction == null) {
146: throw new ServletException("Invalid transaction: "
147: + transactionURI);
148: }
149: return transaction;
150:
151: }
152:
153: }
|