Java tutorial
package com.comcast.locker.gateway.xgateway.service; import static com.comcast.locker.gateway.xgateway.utils.XGatewayUtils.getPrice; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Date; import java.util.List; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.comcast.common.Crn; import com.comcast.config.Configuration; import com.comcast.locker.api.account.AccountId; import com.comcast.locker.api.asset.AssetId; import com.comcast.locker.api.asset.Right; import com.comcast.locker.api.service.LockerService; import com.comcast.locker.api.tx.Transaction; import com.comcast.locker.gateway.services.GatewayService; import com.comcast.locker.gateway.services.UnuService; import com.comcast.locker.gateway.xgateway.XGatewaySettings; import com.comcast.locker.gateway.xgateway.domain.CreatePurchaseRequest; import com.comcast.locker.gateway.xgateway.domain.CreatePurchaseResponse; import com.comcast.locker.gateway.xgateway.utils.XGatewayUtils; import com.comcast.title.Titles; import com.comcast.title.encoding.Api.Title; import com.comcast.title.encoding.Api.TitlePlayability; import com.comcast.util.Pair; /** * Implements the "create permanent buy transaction for XCAL" use case. * */ public class CreatePurchaseForAssetController { private static final Logger LOG = LoggerFactory.getLogger(CreatePurchaseForAssetController.class); private final GatewayService gatewayService; private final LockerService lockerService; private final String cempTransactionHandler; private final UnuService unuService; private final boolean awaitEvidenceOfPlay; public CreatePurchaseForAssetController(Configuration configuration, GatewayService gatewayService, LockerService lockerService, UnuService unuService) { checkNotNull(gatewayService, "The 'gatewayService' cannot be null."); checkNotNull(lockerService, "The 'lockerService' cannot be null."); checkNotNull(configuration, "The 'configuration' cannot be null."); checkNotNull(unuService, "The 'unuService' cannot be null."); this.gatewayService = gatewayService; this.lockerService = lockerService; this.unuService = unuService; this.cempTransactionHandler = configuration.get(XGatewaySettings.TRANSACTION_HANDLER_ID); awaitEvidenceOfPlay = configuration .getAsBoolean(XGatewaySettings.PURCHASE_AWAIT_EVIDENCE_OF_PLAY_BEFORE_BILLING); } /** * "Executes" the use case by:<ol> * <li>Resolving the account number given in the request to a Locker accountId</li> * <li>Resolving the title paid given in the request to a Locker assetId</li> * <li>Creating a full Locker {@link Transaction} with a single associated {@link Right}</li> * <li>Storing the transaction in the Locker</li> * </ol> * * @param purchaseRequest provides the Xgateway specific transaction information */ public CreatePurchaseResponse executePurchaseTransaction(CreatePurchaseRequest purchaseRequest) { checkArgument(purchaseRequest != null, "The 'purchaseRequest' cannot be null."); AccountId accountId = gatewayService.resolveLockerAccountIdFromCRN(purchaseRequest.getAccountId()); AssetId assetId = gatewayService.resolveLockerAssetIdFromCRN(purchaseRequest.getAssetId()); TitlePlayability title = validateRequestInformation(purchaseRequest, accountId, assetId); Pair<Transaction, Date> pair = createPurchaseTransactionInLocker(purchaseRequest, title.getTitle(), accountId, assetId, Crn.fromRawCrn(purchaseRequest.getAssetId()), Crn.fromRawCrn(purchaseRequest.getAccountId())); Transaction tx = pair.getFirst(); CreatePurchaseResponse res = new CreatePurchaseResponse(tx.getId().toString(), tx.getTransactionTime(), pair.getSecond(), tx.getPriceToPurchaser()); return res; } private TitlePlayability validateRequestInformation(CreatePurchaseRequest purchaseRequest, AccountId accountId, AssetId assetId) { TitlePlayability playability = unuService.validatePlayEligibility(assetId, accountId, purchaseRequest.getClient()); //we'll look at rentals if the title is a rental, but if it's a buy, we only care if we own it validateAssetIsNotAlreadyOwned(purchaseRequest.getAccountId(), purchaseRequest.getAssetId(), accountId, assetId, !Titles.titleIsElectronicSellThrough(playability.getTitle()), playability); validateAvailableAndTransaction(playability); Double requestPrice = purchaseRequest.getPrice(); if (requestPrice != null) { if (requestPrice.compareTo(getPrice(playability.getTitle())) != 0) { throw PriceMismatchException.forTitle(requestPrice, getPrice(playability.getTitle())); } } return playability; } private void validateAvailableAndTransaction(TitlePlayability titlePlayability) { switch (titlePlayability.getDecision()) { case PLAYABLE_TITLE: //yippee! break; case PLAYABLE_PREVIEW: throw new AssetIsNotTransactionalException("Cannot purchase a preview asset."); case PLAYABLE_NDVR_TITLE: throw new AssetIsNotTransactionalException("Cannot purchase an NDVR asset."); case NOT_AVAILABLE_ON_VOD_SYSTEM: throw new AssetIsNotAvailableException("Asset not available on CCDN."); case NOT_IN_WINDOW: throw new AssetIsNotAvailableException("License window expired on %1$tm/%1$td/%1$tY.", new Date(titlePlayability.getTitle().getLicenseWindow().getEnd())); case NOT_ENTITLED: throw new AssetIsNotTransactionalException("Cannot purchase a gated asset."); case NOT_ALLOWED_VIA_DL: throw new AssetIsNotAvailableException("Asset is restricted by distribution list."); case NOT_ALLOWED_VIA_MENU_ITEM: throw new AssetIsNotAvailableException("Asset is not available on the VOD menu."); case NOT_ALLOWED_FOR_CREDIT_HOLD: throw new AccountNotInGoodStandingException("Account on credit hold."); case NOT_ALLOWED_FOR_NO_CHARGES_ON_ACCOUNT: throw new AccountNotInGoodStandingException("No charges allowed on account"); case NOT_ALLOWED_FOR_INVALID_HIBIT: throw new AccountNotInGoodStandingException("Account has invalid hibit."); case NOT_ALLOWED_REQUIRES_HDMI: throw new AssetIsNotAvailableException("Asset requires HDMI."); } if (titlePlayability.getTitle().hasService()) { throw new AssetIsNotTransactionalException("Cannot purchase a gated asset."); } if (StringUtils.containsOnly(titlePlayability.getTitle().getPrice(), "$0.")) { throw new AssetIsNotTransactionalException("Cannot purchase a free asset."); } } private void validateAssetIsNotAlreadyOwned(String accountCrn, String assetCrn, AccountId accountId, AssetId assetId, boolean checkRentals, TitlePlayability playability) { if (playability.getTitle().hasRight()) { //call this one first, for owned assets, if you own a higher quality one, you're entitled to //the lower, so if the title comes back with a right for a higher quality asset, //there's no reason to let them buy the lower quality one throw new AssetAlreadyOwnedException(accountCrn, assetCrn); } List<Right> existingRights = lockerService.getAssetRightsByAccountAndAsset(accountId, assetId); for (Right right : existingRights) { if (right.isPermanent() && right.isPlayable()) { throw new AssetAlreadyOwnedException(accountCrn, assetCrn); } if (checkRentals) { if (right.isInWindow() && right.isPlayable()) { throw new AssetAlreadyOwnedException(accountCrn, assetCrn); } } } } private Pair<Transaction, Date> createPurchaseTransactionInLocker(CreatePurchaseRequest purchaseRequest, Title title, AccountId accountId, AssetId assetId, Crn assetCrn, Crn accountCrn) { Pair<Transaction, Date> trans = XGatewayUtils.createPurchaseTransactionForLocker( purchaseRequest.getClient(), cempTransactionHandler, purchaseRequest.getDeviceId(), title, accountId, assetId, assetCrn, accountCrn, awaitEvidenceOfPlay); Date expiration = trans.getSecond(); Transaction lockerTrans = lockerService.createTransaction(trans.getFirst()); return Pair.create(lockerTrans, expiration); } }