Package com.googlecode.memwords.facade.cards

Source Code of com.googlecode.memwords.facade.cards.CardServiceImpl

package com.googlecode.memwords.facade.cards;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.crypto.SecretKey;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.servlet.http.HttpServletResponse;

import org.xml.sax.InputSource;

import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.ResponseTooLargeException;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlecode.memwords.domain.Account;
import com.googlecode.memwords.domain.Card;
import com.googlecode.memwords.domain.CardBasicInformation;
import com.googlecode.memwords.domain.CardBasicInformationComparator;
import com.googlecode.memwords.domain.CardDetails;
import com.googlecode.memwords.facade.util.CryptoEngine;

/**
* Implementation of {@link CardService}
* @author JB
*/
@Singleton
public class CardServiceImpl implements CardService {

    /**
     * The entity manager, used to access the database
     */
    private EntityManager em;

    /**
     * The crypto engine, used to encrypt and decrypt information in the cards
     */
    private CryptoEngine cryptoEngine;

    /**
     * The URL fetch service, used to fetch pages and icons for the URLs of the cards
     */
    private URLFetchService urlFetchService;

    /**
     * The service used to find a fav icon in an HTML document
     */
    private FavIconFinder favIconFinder;

    /**
     * Constructor
     * @param em the entity manager
     * @param cryptoEngine the cryptographic engine
     * @param urlFetchService the URL fetch service
     * @param favIconFinder the fav icon finder
     */
    @Inject
    public CardServiceImpl(EntityManager em,
                           CryptoEngine cryptoEngine,
                           URLFetchService urlFetchService,
                           FavIconFinder favIconFinder) {
        this.em = em;
        this.cryptoEngine = cryptoEngine;
        this.urlFetchService = urlFetchService;
        this.favIconFinder = favIconFinder;
    }

    @Override
    public List<CardBasicInformation> getCards(String userId, SecretKey encryptionKey) {
        List<Card> cards = (em.find(Account.class, userId)).getCards();
        List<CardBasicInformation> result = new ArrayList<CardBasicInformation>(cards.size());
        for (Card card : cards) {
            result.add(new CardBasicInformation(card.getId(),
                                                cryptoEngine.decryptString(card.getName(),
                                                                           encryptionKey,
                                                                           card.getInitializationVector()),
                                                cryptoEngine.decryptString(card.getIconUrl(),
                                                                           encryptionKey,
                                                                           card.getInitializationVector())));
        }
        Collections.sort(result, CardBasicInformationComparator.INSTANCE);
        return result;
    }

    @Override
    public boolean cardExists(String userId,
                              String name,
                              String cardId,
                              SecretKey encryptionKey) {
        List<Card> cards = (em.find(Account.class, userId)).getCards();
        for (Card card : cards) {
            if (!card.getId().equals(cardId)) {
                String cardName =
                    cryptoEngine.decryptString(card.getName(),
                                               encryptionKey,
                                               card.getInitializationVector());
                if (cardName.equals(name)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public Card createCard(String userId, CardDetails cardDetails, SecretKey encryptionKey) {
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            Card card = new Card();
            card.setInitializationVector(cryptoEngine.generateInitializationVector());
            updateCard(card, cardDetails, encryptionKey, true);
            Account account = em.find(Account.class, userId);
            account.addCard(card);
            em.persist(card);
            tx.commit();
            return card;
        }
        finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
    }

    /**
     * Updates the given card with the details found in the given card details
     * @param card the card to update
     * @param cardDetails the new details of the card
     * @param encryptionKey the encryption key used to encrypt information in the card
     * @param modifyPassword if <code>true</code>, updates the password of the card
     * with the one found in the card details. If <code>false</code>, the password isn't updated.
     */
    private void updateCard(Card card,
                            CardDetails cardDetails,
                            SecretKey encryptionKey,
                            boolean modifyPassword) {
        card.setName(cryptoEngine.encryptString(cardDetails.getName(),
                                                encryptionKey,
                                                card.getInitializationVector()));
        card.setLogin(cryptoEngine.encryptString(cardDetails.getLogin(),
                                                 encryptionKey,
                                                 card.getInitializationVector()));
        if (modifyPassword) {
            card.setPassword(cryptoEngine.encryptString(cardDetails.getPassword(),
                                                        encryptionKey,
                                                        card.getInitializationVector()));
        }
        card.setUrl(cryptoEngine.encryptString(cardDetails.getUrl(),
                                               encryptionKey,
                                               card.getInitializationVector()));
        card.setIconUrl(cryptoEngine.encryptString(cardDetails.getIconUrl(),
                                                   encryptionKey,
                                                   card.getInitializationVector()));
        card.setNote(cryptoEngine.encryptString(cardDetails.getNote(),
                                                encryptionKey,
                                                card.getInitializationVector()));
    }

    @Override
    public Card modifyCard(CardDetails cardDetails, SecretKey encryptionKey, boolean modifyPassword) {
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            Card card = em.find(Card.class, cardDetails.getId());
            updateCard(card, cardDetails, encryptionKey, modifyPassword);
            tx.commit();
            return card;
        }
        finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
    }

    @Override
    public CardDetails getCardDetails(String cardId, SecretKey encryptionKey) {
        Card card = em.find(Card.class, cardId);
        if (card == null) {
            return null;
        }
        return new CardDetails(
                card.getId(),
                cryptoEngine.decryptString(card.getName(),
                                           encryptionKey,
                                           card.getInitializationVector()),
                cryptoEngine.decryptString(card.getLogin(),
                                           encryptionKey,
                                           card.getInitializationVector()),
                cryptoEngine.decryptString(card.getPassword(),
                                           encryptionKey,
                                           card.getInitializationVector()),
                cryptoEngine.decryptString(card.getUrl(),
                                           encryptionKey,
                                           card.getInitializationVector()),
                cryptoEngine.decryptString(card.getIconUrl(),
                                           encryptionKey,
                                           card.getInitializationVector()),
                 cryptoEngine.decryptString(card.getNote(),
                                            encryptionKey,
                                            card.getInitializationVector()));

    }

    @Override
    public void deleteCard(String cardId) {
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            Card card = em.find(Card.class, cardId);
            em.remove(card);
            tx.commit();
        }
        finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
    }

    @Override
    public String findFavIconUrl(String urlAsString) throws FavIconException {
        if (!urlAsString.startsWith("http://") && !urlAsString.startsWith("https://")) {
            throw new FavIconException("The URL must start with http:// or https://");
        }

        try {
            URL url = new URL(urlAsString);
            if (url.getHost() == null) {
                throw new FavIconException("The URL must at least contain a host");
            }
            try {
                HTTPResponse response = urlFetchService.fetch(url);
                if (response != null) {
                    URL finalUrl = url;
                    if (response.getFinalUrl() != null) {
                        finalUrl = response.getFinalUrl();
                    }
                    InputSource inputSource =
                        new InputSource(new ByteArrayInputStream(response.getContent()));
                    String iconUrl = favIconFinder.findFavIcon(inputSource, finalUrl);
                    if (iconUrl != null) {
                        return iconUrl;
                    }
                }
                try {
                    URI baseUri = url.toURI();
                    URI defaultFavIconUri = baseUri.resolve("/favicon.ico");
                    response = urlFetchService.fetch(defaultFavIconUri.toURL());
                    if (response == null || response.getResponseCode() != HttpServletResponse.SC_OK) {
                        return null;
                    }
                    else {
                        return defaultFavIconUri.toString();
                    }
                }
                catch (URISyntaxException e) {
                    throw new FavIconException(e);
                }
            }
            catch (IOException e) {
                throw new FavIconException(e);
            }
            catch (ResponseTooLargeException e) {
                throw new FavIconException(e);
            }
        }
        catch (MalformedURLException e) {
            throw new FavIconException(e);
        }
    }
}
TOP

Related Classes of com.googlecode.memwords.facade.cards.CardServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.