Java tutorial
package com.github.jrh3k5.membership.renewal.mailer.service.jpa; /* * #%L * KCAC Membership Management Application * %% * Copyright (C) 2014 Kansas City Atheist Coalition * %% * 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. * #L% */ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.regex.Pattern; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Query; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.jrh3k5.membership.renewal.mailer.service.MembershipService; import com.github.jrh3k5.membership.renewal.mailer.service.jpa.data.JpaMembershipDate; import com.github.jrh3k5.membership.renewal.mailer.service.jpa.data.JpaMembershipRecord; import com.googlecode.jcsv.CSVStrategy; import com.googlecode.jcsv.reader.internal.CSVReaderBuilder; import com.googlecode.jcsv.reader.internal.DefaultCSVEntryParser; public class JpaMembershipService extends AbstractJpaService implements MembershipService<JpaMembershipRecord> { private static final Logger LOGGER = LoggerFactory.getLogger(JpaMembershipService.class); private static final Pattern DATE_PATTERN = Pattern.compile("[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]"); private final EntityManagerFactory entityManagerFactory; @Inject public JpaMembershipService(EntityManagerFactory entityManagerFactory) { super(entityManagerFactory); this.entityManagerFactory = entityManagerFactory; } @Override public void loadMemberships(InputStream csvData) throws IOException { final Reader membershipCsvReader = new InputStreamReader(csvData); try { final DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); for (String[] row : new CSVReaderBuilder<String[]>(membershipCsvReader) .entryParser(new DefaultCSVEntryParser()).strategy(CSVStrategy.UK_DEFAULT).build()) { // Index 1 - date of membership // Index 4 - Name, full // Not all rows may be actual membership data if (row.length < 5) { continue; } if (!DATE_PATTERN.matcher(row[1]).matches()) { continue; } // Skip blank names if (StringUtils.isBlank(row[4])) { continue; } final String[] splitName = row[4].split(" "); final String givenName = splitName[0]; final String familyName = splitName[splitName.length - 1]; Date membershipDate; try { membershipDate = dateFormat.parse(row[1]); } catch (ParseException e) { throw new IOException(String.format("Failed to parse date %s for %s", row[1], row[4])); } addMembershipRecord(givenName, familyName, membershipDate); } } finally { membershipCsvReader.close(); } } @Override public JpaMembershipRecord addMembershipRecord(String givenName, String familyName, Date membershipDate) { // Does the record already exist? If so, update it // Do it within an entity so that the dates collection can be modified while attached final EntityManager entityManager = entityManagerFactory.createEntityManager(); try { final JpaMembershipRecord byName = getByName(entityManager, givenName, familyName); if (byName != null) { byName.addMembershipDate(membershipDate); updateMembership(entityManager, byName); return byName; } } finally { entityManager.close(); } final JpaMembershipRecord newRecord = new JpaMembershipRecord(); newRecord.setFamilyName(familyName); newRecord.setGivenName(givenName); newRecord.addMembershipDate(membershipDate); persistEntity(newRecord); return newRecord; } @Override public JpaMembershipRecord getByName(String givenName, String familyName) { final EntityManager entityManager = entityManagerFactory.createEntityManager(); try { return getByName(entityManager, givenName, familyName); } finally { entityManager.close(); } } private JpaMembershipRecord getByName(EntityManager entityManager, String givenName, String familyName) { final Query query = entityManager.createQuery( "select m from MembershipRecord m where m.givenName = :givenName and m.familyName = :familyName"); query.setParameter("givenName", givenName); query.setParameter("familyName", familyName); @SuppressWarnings("unchecked") final List<JpaMembershipRecord> results = query.getResultList(); return results.size() == 1 ? results.get(0) : null; } @SuppressWarnings("unchecked") @Override public Collection<JpaMembershipRecord> getLapsedMemberships(Date lowerExclusiveBound, Date upperInclusiveBound) { LOGGER.info("Finding members who have lapsed memberships between ({}, {}]", lowerExclusiveBound, upperInclusiveBound); final EntityManager entityManager = entityManagerFactory.createEntityManager(); try { final Query query = entityManager.createQuery( "select m from MembershipRecord m where m.latestMembershipDate > :lowerBound and m.latestMembershipDate <= :upperBound"); query.setParameter("lowerBound", lowerExclusiveBound); query.setParameter("upperBound", upperInclusiveBound); return query.getResultList(); } finally { entityManager.close(); } } @Override public void updateMembership(JpaMembershipRecord membership) { final EntityManager entityManager = entityManagerFactory.createEntityManager(); try { updateMembership(entityManager, membership); } finally { entityManager.close(); } } private void updateMembership(EntityManager entityManager, JpaMembershipRecord membership) { final EntityTransaction transaction = entityManager.getTransaction(); try { transaction.begin(); entityManager.merge(membership); transaction.commit(); } catch (RuntimeException e) { transaction.rollback(); throw e; } } @Override public long getMemberCount() { return getEntityCount(JpaMembershipRecord.class); } @Override public long getRecordCount() { return getEntityCount(JpaMembershipDate.class); } }