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: /**
030: * A transaction holds the state and information about payment. It's state
031: * is updated by the associated transaction processor.
032: * <p>
033: * There are the following predefined states:
034: * <ul>
035: * <li><code>ENTERED</code> - the payment has been initiated by the
036: * application
037: * </li>
038: * <li><code>UPDATE</code> - the transaction should be updated from the
039: * update URL
040: * </li>
041: * <li><code>ASSIGNED</code> - the transaction has been assigned to the
042: * payment adapter instance associated with the user selected
043: * provider
044: * </li>
045: * <li><code>SUCCESSFUL</code> - the payment has been successfully finished
046: * </li>
047: * <li><code>FAILED</code> - the payment failed because of errors
048: * </li>
049: * <li><code>REJECTED</code> - the payment has been rejected by the user
050: * </li>
051: * <li><code>DISCARDED</code> - the transaction should be silently
052: * discarded by the payment module
053: * </li>
054: * </ul>
055: * <p>
056: * The <code>Transaction</code> class can be extended by some adapter specific
057: * subclass, which can hold more information about payment and can define some
058: * adapter specific states. For this purpose, there is a special constructor
059: * which initiates the transaction from the information provided by the
060: * transaction given as a parameter. There is also defined the
061: * <code>ADAPTER_SPECIFIC</code> constant, which should be used to number
062: * adapter specific states (<code>ADAPTER_SPECIFIC</code>,
063: * <code>ADAPTER_SPECIFIC + 1</code>, <code>ADAPTER_SPECIFIC + 2</code>...).
064: *
065: * @version 1.7
066: */
067: public class Transaction {
068:
069: /** A predefined transaction state. */
070: public static final int ENTERED = 0;
071: /** A predefined transaction state. */
072: public static final int UPDATE = 1;
073: /** A predefined transaction state. */
074: public static final int ASSIGNED = 2;
075: /** A predefined transaction state. */
076: public static final int SUCCESSFUL = 3;
077: /** A predefined transaction state. */
078: public static final int FAILED = 4;
079: /** A predefined transaction state. */
080: public static final int REJECTED = 5;
081: /** A predefined transaction state. */
082: public static final int DISCARDED = 6;
083:
084: /** The starting value of adapter specific states. */
085: protected static final int ADAPTER_SPECIFIC = 0x100;
086:
087: private int transactionID;
088:
089: private int featureID;
090: private String featureTitle;
091: private String featureDescription;
092: private byte[] payload;
093:
094: private TransactionModuleImpl transactionModule;
095:
096: private String providerName;
097: private String currency;
098: private double price;
099: private String specificPriceInfo;
100:
101: private int state;
102:
103: private boolean waiting;
104: private boolean needsUI;
105:
106: private TransactionProcessor processor;
107:
108: /**
109: * Creates a new instance of <code>Transaction</code>.
110: *
111: * @param processor the initial transaction processor responsible for
112: * processing of this transaction
113: * @param module the transaction module associated with the transaction
114: * @param featureID the identifier of the feature to be paid for
115: * @param featureTitle the title of the feature
116: * @param featureDescription the description of the feature
117: * @param payload the payload to be transfered as a part of the payment or
118: * <code>null</code> if no such payload required
119: */
120: Transaction(TransactionProcessor processor,
121: TransactionModuleImpl module, int featureID,
122: String featureTitle, String featureDescription,
123: byte[] payload) {
124:
125: this .transactionModule = module;
126:
127: this .featureID = featureID;
128: this .featureTitle = featureTitle;
129: this .featureDescription = featureDescription;
130: this .payload = payload;
131:
132: this .processor = processor;
133: this .needsUI = true;
134: }
135:
136: /**
137: * Creates a new instance of <code>Transaction</code> with the fields
138: * initialized from the given original transaction.
139: *
140: * @param templ the original transaction
141: */
142: public Transaction(Transaction templ) {
143: transactionID = templ.transactionID;
144:
145: featureID = templ.featureID;
146: featureTitle = templ.featureTitle;
147: featureDescription = templ.featureDescription;
148: payload = templ.payload;
149: transactionModule = templ.transactionModule;
150:
151: providerName = templ.providerName;
152: currency = templ.currency;
153: price = templ.price;
154: specificPriceInfo = templ.specificPriceInfo;
155:
156: state = templ.state;
157:
158: waiting = templ.waiting;
159: needsUI = templ.needsUI;
160:
161: processor = templ.processor;
162: }
163:
164: /**
165: * Returns the title of the feature, which is paid for by this transaction.
166: *
167: * @return the title of the feature
168: */
169: public final String getFeatureTitle() {
170: return featureTitle;
171: }
172:
173: /**
174: * Returns the description of the feature, which is paid for by this
175: * transaction.
176: *
177: * @return the description of the feature
178: */
179: public final String getFeatureDescription() {
180: return featureDescription;
181: }
182:
183: /**
184: * Returns the payload which is a part of the payment or <code>null</code>
185: * if it's undefined.
186: *
187: * @return the payload or <code>null</code>
188: */
189: public final byte[] getPayload() {
190: return payload;
191: }
192:
193: /**
194: * Returns the payload which is a part of the payment or <code>null</code>
195: * if it's undefined.
196: *
197: * @return the payload or <code>null</code>
198: */
199: public final String getProviderName() {
200: return providerName;
201: }
202:
203: /**
204: * Returns the currency of the payment.
205: *
206: * @return the currency of the payment
207: */
208: public final String getCurrency() {
209: return currency;
210: }
211:
212: /**
213: * Returns the price of the feature, which is paid.
214: *
215: * @return the price of the feature
216: */
217: public final double getPrice() {
218: return price;
219: }
220:
221: /**
222: * Returns the provider specific price information associated with
223: * the paid feature.
224: *
225: * @return the provider specific price information
226: */
227: public final String getSpecificPriceInfo() {
228: return specificPriceInfo;
229: }
230:
231: /**
232: * Sets the transaction processor of the transaction.
233: *
234: * @param processor the new transaction processor
235: */
236: public void setTransactionProcessor(TransactionProcessor processor) {
237: this .processor = processor;
238: }
239:
240: /**
241: * Puts the transaction into or resumes it from the waiting. A transaction
242: * which is waiting is not processed by the transaction processing thread
243: * of the payment module (its state doesn't change). A transaction can wait
244: * for some user response or the end of some adapter specific thread.
245: *
246: * @param value if <code>true</code> the transaction is entering the
247: * waiting, if <code>false</code> the transaction is ending its waiting
248: */
249: public final void setWaiting(boolean value) {
250: // should be synchronized?
251: if (waiting == value) {
252: return;
253: }
254: if (waiting) {
255: waiting = false;
256: // notify the payment module
257: PaymentModule.getInstance().continueProcessing();
258: return;
259: }
260: waiting = true;
261: }
262:
263: /**
264: * Indicates if the transaction is waiting for some event.
265: *
266: * @return <code>true</code> if the transaction is waiting
267: */
268: public final boolean isWaiting() {
269: return waiting;
270: }
271:
272: /**
273: * Sets the value which indicates if the transaction needs or will need
274: * some user response to be finished. Setting this value to
275: * <code>true</code> can block this or other transactions that also need
276: * user response from processing (only one such transaction can be
277: * processed at a time). Initialy this value is set to <code>true</code>
278: * and is an adapter responsibility to set it to <code>false</code> at the
279: * right time.
280: *
281: * @param value <code>true</code> if the transaction needs or will need
282: * an user response to be finished
283: */
284: public final void setNeedsUI(boolean value) {
285: needsUI = value;
286: }
287:
288: /**
289: * Indicates if the transaction needs or will need an user response to be
290: * finished.
291: *
292: * @return <code>true</code> if the transaction needs an user response
293: */
294: public final boolean needsUI() {
295: return needsUI;
296: }
297:
298: /**
299: * Sets the state of the transaction to the new value.
300: *
301: * @param newState the new state
302: * @see #getState
303: */
304: public final void setState(int newState) {
305: state = newState;
306: }
307:
308: /**
309: * Returns the current state of the transaction.
310: *
311: * @return the current state
312: * @see #setState
313: */
314: public final int getState() {
315: return state;
316: }
317:
318: /**
319: * Returns the transaction ID value.
320: *
321: * @return the transaction ID
322: */
323: public final int getTransactionID() {
324: return transactionID;
325: }
326:
327: /**
328: * Returns the id of the paid feature.
329: *
330: * @return the feature id
331: */
332: public final int getFeatureID() {
333: return featureID;
334: }
335:
336: /**
337: * Returns the associated transaction module.
338: *
339: * @return the transaction module
340: */
341: public final TransactionModuleImpl getTransactionModule() {
342: return transactionModule;
343: }
344:
345: /**
346: * Processes the transaction. Delegates the call to the associated
347: * transaction processor.
348: *
349: * @return the fully or partially processed transaction.
350: */
351: final Transaction process() {
352: return processor.process(this );
353: }
354:
355: /**
356: * Sets the transaction ID for the transaction.
357: *
358: * @param value the new transaction ID value
359: */
360: final void setTransactionID(int value) {
361: transactionID = value;
362: }
363:
364: /**
365: * Sets the name of the selected provider.
366: *
367: * @param value the new provider name
368: */
369: final void setProviderName(String value) {
370: providerName = value;
371: }
372:
373: /**
374: * Sets the currency of the payment.
375: *
376: * @param value the currency
377: */
378: final void setCurrency(String value) {
379: currency = value;
380: }
381:
382: /**
383: * Sets the price of the paid feature.
384: *
385: * @param value the price
386: */
387: final void setPrice(double value) {
388: price = value;
389: }
390:
391: /**
392: * Sets the provider specific price information.
393: *
394: * @param value the provider specific price information
395: */
396: final void setSpecificPriceInfo(String value) {
397: specificPriceInfo = value;
398: }
399: }
|