fr.aliacom.obm.common.addition.CommitedOperationDaoJdbcImpl.java Source code

Java tutorial

Introduction

Here is the source code for fr.aliacom.obm.common.addition.CommitedOperationDaoJdbcImpl.java

Source

/* ***** BEGIN LICENSE BLOCK *****
 * 
 * Copyright (C) 2011-2014  Linagora
 *
 * This program is free software: you can redistribute it and/or 
 * modify it under the terms of the GNU Affero General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version, provided you comply 
 * with the Additional Terms applicable for OBM connector by Linagora 
 * pursuant to Section 7 of the GNU Affero General Public License, 
 * subsections (b), (c), and (e), pursuant to which you must notably (i) retain 
 * the Message sent thanks to OBM, Free Communication by Linagora? 
 * signature notice appended to any and all outbound messages 
 * (notably e-mail and meeting requests), (ii) retain all hypertext links between 
 * OBM and obm.org, as well as between Linagora and linagora.com, and (iii) refrain 
 * from infringing Linagora intellectual property rights over its trademarks 
 * and commercial brands. Other Additional Terms apply, 
 * see <http://www.linagora.com/licenses/> for more details. 
 *
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License 
 * for more details. 
 *
 * You should have received a copy of the GNU Affero General Public License 
 * and its applicable Additional Terms for OBM along with this program. If not, 
 * see <http://www.gnu.org/licenses/> for the GNU Affero General Public License version 3 
 * and <http://www.linagora.com/licenses/> for the Additional Terms applicable to 
 * OBM connectors. 
 * 
 * ***** END LICENSE BLOCK ***** */
package fr.aliacom.obm.common.addition;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.codec.binary.Base64;
import org.obm.sync.addition.CommitedElement;
import org.obm.sync.addition.Kind;
import org.obm.sync.auth.AccessToken;
import org.obm.sync.auth.EventNotFoundException;
import org.obm.sync.auth.ServerFault;
import org.obm.sync.book.Contact;
import org.obm.sync.calendar.Event;
import org.obm.sync.calendar.EventObmId;
import org.obm.sync.exception.ContactNotFoundException;
import org.obm.utils.ObmHelper;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import fr.aliacom.obm.common.calendar.CalendarDao;
import fr.aliacom.obm.common.contact.ContactDao;

/**
 * Calendar data access functions
 */
@Singleton
public class CommitedOperationDaoJdbcImpl implements CommitedOperationDao {

    private final ObmHelper obmHelper;
    private final CalendarDao calendarDao;
    private final ContactDao contactDao;

    @Inject
    @VisibleForTesting
    CommitedOperationDaoJdbcImpl(ObmHelper obmHelper, CalendarDao calendarDao, ContactDao contactDao) {
        this.obmHelper = obmHelper;
        this.calendarDao = calendarDao;
        this.contactDao = contactDao;
    }

    @Override
    public void store(AccessToken at, CommitedElement commitedElement) throws SQLException, ServerFault {
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = obmHelper.getConnection();

            if (operationIsAlreadyRecorded(con, commitedElement)) {
                ps = prepareUpdateStatement(con, commitedElement);
            } else {
                ps = prepareInsertStatement(con, commitedElement);
            }
            ps.executeUpdate();
        } finally {
            obmHelper.cleanup(con, ps, null);
        }
    }

    private boolean operationIsAlreadyRecorded(Connection con, CommitedElement commitedElement)
            throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement("SELECT commitedoperation_hash_client_id " + "FROM CommitedOperation "
                    + "WHERE commitedoperation_hash_client_id = ? ");

            ps.setString(1, commitedElement.getClientId());

            rs = ps.executeQuery();
            return rs.next();
        } finally {
            obmHelper.cleanup(null, ps, rs);
        }
    }

    private PreparedStatement prepareInsertStatement(Connection con, CommitedElement commitedElement)
            throws SQLException {
        PreparedStatement ps = con.prepareStatement("INSERT INTO CommitedOperation "
                + "(commitedoperation_hash_client_id, commitedoperation_entity_id, commitedoperation_kind) "
                + "VALUES (?, ?, ?) ");
        int idx = 1;
        try {
            ps.setString(idx++, commitedElement.getClientId());
            ps.setInt(idx++, commitedElement.getEntityId().getId());
            ps.setObject(idx++, getJdbcObject(commitedElement.getKind()));
            return ps;
        } catch (SQLException e) {
            ps.close();
            throw e;
        } catch (RuntimeException e) {
            ps.close();
            throw e;
        }
    }

    private PreparedStatement prepareUpdateStatement(Connection con, CommitedElement commitedElement)
            throws SQLException {
        PreparedStatement ps = con.prepareStatement("UPDATE CommitedOperation "
                + "SET commitedoperation_entity_id=? " + "WHERE commitedoperation_hash_client_id=? ");
        try {
            int idx = 1;
            ps.setInt(idx++, commitedElement.getEntityId().getId());
            ps.setString(idx++, commitedElement.getClientId());
            return ps;
        } catch (SQLException e) {
            ps.close();
            throw e;
        } catch (RuntimeException e) {
            ps.close();
            throw e;
        }
    }

    @Override
    public Event findAsEvent(AccessToken token, String clientId) throws SQLException, ServerFault {

        if (clientId == null) {
            return null;
        }

        checkClientIdFormat(clientId);

        String q = "SELECT e.evententity_event_id FROM CommitedOperation a "
                + "INNER JOIN EventEntity e ON a.commitedoperation_entity_id=evententity_entity_id "
                + "WHERE commitedoperation_hash_client_id = ? AND commitedoperation_kind = ?";

        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = obmHelper.getConnection();
            ps = con.prepareStatement(q);

            int idx = 1;
            ps.setString(idx++, clientId);
            ps.setObject(idx++, getJdbcObject(Kind.VEVENT));
            rs = ps.executeQuery();

            Event ret = null;
            if (rs.next()) {
                int id = rs.getInt(1);
                EventObmId eventObmId = new EventObmId(id);
                try {
                    ret = calendarDao.findEventById(token, eventObmId);
                } catch (EventNotFoundException e) {
                }
            }
            return ret;

        } finally {
            obmHelper.cleanup(con, ps, rs);
        }
    }

    @Override
    public Contact findAsContact(AccessToken token, String clientId) throws SQLException {

        if (clientId == null) {
            return null;
        }

        checkClientIdFormat(clientId);

        String q = "SELECT c.contactentity_contact_id FROM CommitedOperation a "
                + "INNER JOIN ContactEntity c ON a.commitedoperation_entity_id=contactentity_entity_id "
                + "WHERE commitedoperation_hash_client_id = ? AND commitedoperation_kind = ?";

        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = obmHelper.getConnection();
            ps = con.prepareStatement(q);

            int idx = 1;
            ps.setString(idx++, clientId);
            ps.setObject(idx++, getJdbcObject(Kind.VCONTACT));
            rs = ps.executeQuery();

            Contact ret = null;
            if (rs.next()) {
                int id = rs.getInt(1);
                try {
                    ret = contactDao.findContact(token, id);
                } catch (ContactNotFoundException e) {
                }
            }
            return ret;

        } finally {
            obmHelper.cleanup(con, ps, rs);
        }
    }

    private Object getJdbcObject(Kind kind) throws SQLException {
        return obmHelper.getDBCP().getJdbcObject(ObmHelper.VKIND, kind.toString());
    }

    @VisibleForTesting
    void checkClientIdFormat(String clientId) {
        Preconditions.checkArgument(clientId.length() == 40, "clientId must have a length of 40 characters");
        Preconditions.checkArgument(Base64.isBase64(clientId), "clientId must be in base 64");
    }
}