001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.j2me.payment;
028:
029: import com.sun.midp.security.*;
030:
031: import javax.microedition.lcdui.Displayable;
032:
033: /**
034: * This class represents an adapter which is responsible for handling of
035: * transactions with an assigned provider. Each instance should be responsible
036: * for some provider specific payment method (one instance of premium priced
037: * SMS adapter for each PPSMS provider).
038: *
039: * @version 1.3
040: */
041: public abstract class PaymentAdapter implements TransactionProcessor {
042: /**
043: * Replaces the current <code>Displayable</code> with the new one if the
044: * <code>nextDisplayable</code> is not <code>null</code> or it recovers
045: * the previous <code>Displayable</code> if the <code>nextDisplayable</code>
046: * is <code>null</code>.
047: *
048: * @param token a security token, which allows preempting
049: * @param nextDisplayable the <code>Displayable</code> to show or
050: * <code>null</code> if the recovery of the old
051: * <code>Displayable</code> is requested
052: */
053: protected final void preemptDisplay(SecurityToken token,
054: Displayable nextDisplayable) {
055: PaymentModule.getInstance().preemptDisplay(token,
056: nextDisplayable);
057: }
058:
059: /**
060: * Validates the price information which are specified in the application
061: * manifest file for the provider handled by this adapter. It throws an
062: * <code>PaymentException</code> if the parameters are incorrect.
063: *
064: * @param price the price to pay when using this provider
065: * @param paySpecificPriceInfo the specific price information string from
066: * the manifest
067: * @throws PaymentException if the provided information is correct
068: */
069: public void validatePriceInfo(double price,
070: String paySpecificPriceInfo) throws PaymentException {
071: }
072:
073: /**
074: * Returns a display name for this particular adapter. It should represent
075: * a payment method (premium priced sms, credit card...).
076: *
077: * @return the display name
078: */
079: public abstract String getDisplayName();
080:
081: /**
082: * Returns a question which is used for this adapter instance when the
083: * user chooses between providers for the particular payment.
084: *
085: * @param provider the application supplied provider name
086: * @param price the price to pay when using the provider
087: * @param currency the currency of the payment
088: * @return the question to ask (Are you sure, you want to buy this
089: * feature...)
090: */
091: public String getPaymentQuestion(String provider, double price,
092: String currency) {
093: int multiplied = (int) (price * 100 + 0.5);
094: String priceString = Integer.toString(multiplied);
095: int length = priceString.length();
096:
097: String[] values = { currency,
098: priceString.substring(0, length - 2),
099: priceString.substring(length - 2), getDisplayName(),
100: provider };
101:
102: return PaymentModule.getInstance().getUtilities().getString(
103: Utils.PAYMENT_UPDATE_DLG_QUESTION, values);
104: }
105:
106: /**
107: * Processes the given transaction, updates its state and returns the same
108: * transaction instance or a new one (an instance of
109: * a <code>Transaction</code> subclass), which is based on the old
110: * transaction, but adds more (adapter specific) information to it.
111: *
112: * The current implementation fails any transaction with the
113: * <code>Transaction.ASSIGNED</code> state, so it has to be overriden to
114: * work properly. It also sets the transaction processor of the given
115: * transaction to the payment module instance. It's recomended to call
116: * this method from the overriden one for every unhandled transaction
117: * (with the state, which can't be further processed in the adapter).
118: * It ensures that the control over the transaction will return to the
119: * payment module.
120: *
121: * @param transaction the transaction to be processed
122: * @return the transaction after processing
123: */
124: public Transaction process(Transaction transaction) {
125: if (transaction.getState() == Transaction.ASSIGNED) {
126: // was not processed by the child adapter class
127: transaction.setState(Transaction.FAILED);
128: transaction.setNeedsUI(false);
129: }
130:
131: // return any transaction which was not processed by the payment
132: // adapter back to the payment module
133: transaction
134: .setTransactionProcessor(PaymentModule.getInstance());
135: return transaction;
136: }
137: }
|