/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.springsource.greenhouse.invite; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import javax.inject.Inject; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import com.springsource.greenhouse.account.Account; import com.springsource.greenhouse.account.ProfileReference; import com.springsource.greenhouse.activity.action.ActionFactory; import com.springsource.greenhouse.activity.action.ActionRepository; import com.springsource.greenhouse.utils.Location; /** * InviteRepository implementation that stores Invites in a relational database using a JDBC API. * @author Keith Donald */ @Repository public class JdbcInviteRepository implements InviteRepository { private final JdbcTemplate jdbcTemplate; private final ActionRepository actionRepository; @Inject public JdbcInviteRepository(JdbcTemplate jdbcTemplate, ActionRepository actionRepository) { this.jdbcTemplate = jdbcTemplate; this.actionRepository = actionRepository; } public boolean alreadyInvited(String email) { return jdbcTemplate.queryForObject("select exists(select 1 from Invite where email = ?)", Boolean.class, email) || jdbcTemplate.queryForObject("select exists(select 1 from Member where email = ?)", Boolean.class, email); } public void saveInvite(String token, Invitee invitee, String text, Long sentBy) { jdbcTemplate.update(INSERT_INVITE, token, invitee.getEmail(), invitee.getFirstName(), invitee.getLastName(), text, sentBy); } public void markInviteAccepted(final String token, Account account) { actionRepository.saveAction(InviteAcceptAction.class, account, new ActionFactory<InviteAcceptAction>() { public InviteAcceptAction createAction(Long id, DateTime time, Account account, Location location) { jdbcTemplate.update("insert into InviteAcceptAction (invite, memberAction) values (?, ?)", token, id); Map<String, Object> invite = jdbcTemplate.queryForMap("select sentBy, sentTime from Invite where token = ?", token); Long sentBy = (Long) invite.get("sentBy"); DateTime sentTime = new DateTime(invite.get("sentTime"), DateTimeZone.UTC); return new InviteAcceptAction(id, time, account, location, sentBy, sentTime); } }); } public Invite findInvite(String token) throws NoSuchInviteException, InviteAlreadyAcceptedException { Invite invite = queryForInvite(token); if (invite.isAccepted()) { throw new InviteAlreadyAcceptedException(token); } return invite; } // internal helpers private Invite queryForInvite(String token) throws NoSuchInviteException { try { return jdbcTemplate.queryForObject(SELECT_INVITE, new RowMapper<Invite>() { public Invite mapRow(ResultSet rs, int rowNum) throws SQLException { Invitee invitee = new Invitee(rs.getString("firstName"), rs.getString("lastName"), rs.getString("email")); ProfileReference sentBy = ProfileReference.textOnly(rs.getLong("sentById"), rs.getString("sentByUsername"), rs.getString("sentByFirstName"), rs.getString("sentByLastName")); return new Invite(invitee, sentBy, rs.getBoolean("accepted")); } }, token, token); } catch (EmptyResultDataAccessException e) { throw new NoSuchInviteException(token); } } private static final String INSERT_INVITE = "insert into Invite (token, email, firstName, lastName, text, sentBy) values (?, ?, ?, ?, ?, ?)"; private static final String SELECT_INVITE = "select i.email, i.firstName, i.lastName, m.id as sentById, m.username as sentByUsername, m.firstName as sentByFirstName, m.lastName as sentByLastName, exists(select 1 from InviteAcceptAction where invite = ?) as accepted from Invite i inner join Member m on i.sentBy = m.id where i.token = ?"; }