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 javax.microedition.midlet.MIDlet;
030:
031: import java.io.IOException;
032: import java.util.Random;
033:
034: import javax.microedition.payment.TransactionListener;
035: import javax.microedition.payment.TransactionRecord;
036: import javax.microedition.payment.TransactionModuleException;
037: import javax.microedition.payment.TransactionFeatureException;
038: import javax.microedition.payment.TransactionListenerException;
039: import javax.microedition.payment.TransactionPayloadException;
040:
041: import com.sun.midp.security.Permissions;
042:
043: /**
044: * This class holds a "real" implementation of the transaction module. All
045: * calls to a transaction module instance are delegated to the instance of this
046: * class which has been associated with the delegating instance.
047: *
048: * @version
049: */
050: public abstract class TransactionModuleImpl {
051: /** The caller MIDlet. */
052: protected MIDlet midlet;
053: /**
054: * The listener set by the application or <code>null</code> if hasn't been
055: * set.
056: */
057: protected TransactionListener listener;
058:
059: /** The size limit of a payload from the specification. */
060: public static final int PAYLOAD_LIMIT = 132;
061:
062: /**
063: * Creates a new instance of <code>TransactionModuleImpl</code>. It
064: * requires a reference to the object, which originated the call. This
065: * object should be a MIDlet.
066: *
067: * @param object the caller MIDlet
068: * @throws TransactionModuleException indicates an error preventing the
069: * MIDlet from using the payment API
070: * @see javax.microedition.payment.TransactionModule#TransactionModule
071: */
072: protected TransactionModuleImpl(Object object)
073: throws TransactionModuleException {
074: if (object == null) {
075: throw new NullPointerException();
076: }
077: if (!(object instanceof MIDlet)) {
078: throw new TransactionModuleException(
079: "The object is not referring to the application");
080: }
081: midlet = (MIDlet) object;
082:
083: }
084:
085: /**
086: * Sets the listener which should be notified about finishing of
087: * transactions or removes the listener which has been set before if
088: * <code>listener</code> is <code>null</code>.
089: *
090: * @param listener the new listener or <code>null</code>
091: * @see javax.microedition.payment.TransactionModule#setListener
092: */
093: synchronized public final void setListener(
094: TransactionListener listener) {
095: this .listener = listener;
096: }
097:
098: /**
099: * Initiates a new payment transaction from the given input values.
100: *
101: * @param featureID the feature ID
102: * @param featureTitle the feature title
103: * @param featureDescription the feature description
104: * @param payload the payload
105: * @return the ID of the new transaction
106: * @throws TransactionModuleException indicates incorrect input parameters
107: * or overloading of the payment module
108: * @throws TransactionFeatureException if the <code>featureID</code> is
109: * incorrect
110: * @throws TransactionListenerException if the transaction listener hasn't
111: * been set prior the call
112: * @throws TransactionPayloadException if the payload exceed the limit
113: * allowed by the specification
114: * @see javax.microedition.payment.TransactionModule#process
115: * @see javax.microedition.payment.TransactionModuleException
116: * @see javax.microedition.payment.TransactionFeatureException
117: * @see javax.microedition.payment.TransactionListenerException
118: * @see javax.microedition.payment.TransactionPayloadException
119: */
120: public final int process(int featureID, String featureTitle,
121: String featureDescription, byte[] payload)
122: throws TransactionModuleException,
123: TransactionFeatureException, TransactionListenerException,
124: TransactionPayloadException {
125:
126: // check for the javax.microedition.payment.process permission
127: try {
128: checkForPermission(Permissions.PAYMENT, null);
129: } catch (InterruptedException e) {
130: throw new SecurityException();
131: }
132:
133: // null featureTitle or featureDescription
134: if ((featureTitle == null) || (featureDescription == null)) {
135: throw new TransactionModuleException("The "
136: + ((featureTitle == null) ? "featureTitle"
137: : "featureDescription") + " is null");
138: }
139:
140: // empty featureTitle or featureDescription
141: if ((featureTitle.length() == 0)
142: || (featureDescription.length() == 0)) {
143: throw new TransactionModuleException("The "
144: + ((featureTitle.length() == 0) ? "featureTitle"
145: : "featureDescription") + " is empty");
146: }
147:
148: // payload limit exceeded
149: if ((payload != null) && (payload.length > PAYLOAD_LIMIT)) {
150: throw new TransactionPayloadException();
151: }
152:
153: // invalid feature ID
154: if ((featureID < 0)
155: || (featureID >= getPaymentInfo().getNumFeatures())) {
156: throw new TransactionFeatureException();
157: }
158:
159: // listener hasn't been set
160: if (listener == null) {
161: throw new TransactionListenerException();
162: }
163:
164: return PaymentModule.getInstance().addTransaction(this ,
165: featureID, featureTitle, featureDescription, payload);
166: }
167:
168: /**
169: * Returns an array of <code>TransactionRecord</code> objects that
170: * represent the past transactions, initiated by the MIDlet and about whose
171: * final state the MIDlet has been already notified.
172: *
173: * @param max limits the number of returned transaction records
174: * @return an array of the transaction records or <code>null</code> if
175: * <code>max</code> is set to <code>0</code> or there is no transaction
176: * to return
177: * @see javax.microedition.payment.TransactionModule#getPastTransactions
178: */
179: public final TransactionRecord[] getPastTransactions(int max) {
180: if (max == 0) {
181: return null;
182: }
183:
184: TransactionRecord[] allPassed = getPassedTransactions();
185:
186: if ((allPassed == null) || (allPassed.length <= max)) {
187: return allPassed;
188: }
189:
190: TransactionRecord[] truncated = new TransactionRecord[max];
191: System.arraycopy(allPassed, 0, truncated, 0, max);
192:
193: return truncated;
194: }
195:
196: /**
197: * Makes the payment module to notify the listener about the MIDlet
198: * transactions which the listener couldn't have been notified about before
199: * (the MIDlet crashed or ended before the notification could take place).
200: *
201: * @throws TransactionListenerException if the transaction listener hasn't
202: * been set prior the call
203: * @see
204: * javax.microedition.payment.TransactionModule#deliverMissedTransactions
205: */
206: public void deliverMissedTransactions()
207: throws TransactionListenerException {
208: if (listener == null) {
209: throw new TransactionListenerException();
210: }
211:
212: TransactionRecord[] allMissed = getMissedTransactions();
213:
214: if (allMissed != null) {
215: PaymentModule.getInstance().addTransactionsForNotification(
216: allMissed, this );
217: }
218: }
219:
220: /**
221: * Returns the MIDlet.
222: *
223: * @return the MIDlet
224: */
225: public final MIDlet getMIDlet() {
226: return midlet;
227: }
228:
229: /**
230: * Returns an array of the missed transactions associated with the MIDlet
231: * suite.
232: *
233: * @return an array of the missed transactions
234: */
235: protected TransactionRecord[] getMissedTransactions() {
236: int applicationID = getApplicationID();
237:
238: TransactionStore transactionStore = PaymentModule.getInstance()
239: .getTransactionStore();
240: TransactionRecord[] allMissed = null;
241:
242: try {
243: allMissed = transactionStore
244: .getMissedTransactions(applicationID);
245: } catch (IOException e) {
246: }
247:
248: return allMissed;
249: }
250:
251: /**
252: * Returns an array of the passed transactions associated with the MIDlet
253: * suite.
254: *
255: * @return an array of the passed transactions
256: */
257: protected TransactionRecord[] getPassedTransactions() {
258: int applicationID = getApplicationID();
259:
260: TransactionStore transactionStore = PaymentModule.getInstance()
261: .getTransactionStore();
262: TransactionRecord[] allPassed = null;
263:
264: try {
265: allPassed = transactionStore
266: .getPassedTransactions(applicationID);
267: } catch (IOException e) {
268: }
269:
270: return allPassed;
271: }
272:
273: /**
274: * Returns the transaction listener.
275: *
276: * @return the transaction listener
277: */
278: final TransactionListener getListener() {
279: return listener;
280: }
281:
282: /**
283: * Ensures that the MIDlet will have required privileges to do a protected
284: * operation.
285: *
286: * @param permission the required permission
287: * @param name an additional info string
288: * @throws SecurityException if the permission is not granted
289: * @throws InterruptedException if the thread waiting for the permission
290: * is interrupted
291: */
292: protected abstract void checkForPermission(int permission,
293: String name) throws InterruptedException;
294:
295: /**
296: * Returns the payment provisioning information associated with the MIDlet.
297: *
298: * @return the payment provisioning information
299: */
300: protected abstract PaymentInfo getPaymentInfo();
301:
302: /**
303: * Stores the payment provisioning information associated with the MIDlet.
304: *
305: * @throws IOException indicates an output error
306: */
307: protected abstract void savePaymentInfo() throws IOException;
308:
309: /**
310: * Returns the MIDlet payment ID that can be used to store transaction
311: * records for the MIDlet initiated transactions into the transaction store.
312: *
313: * @return the ID
314: */
315: protected abstract int getApplicationID();
316: }
|