Java tutorial
/* * Copyright 2010 Chad Retz * * 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 org.statmantis.mport.retro.event; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.http.HttpEntity; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.statmantis.model.Person; import org.statmantis.model.Roster; import org.statmantis.mport.retro.RetrosheetContext; import org.statmantis.mport.retro.RetrosheetReader; import org.statmantis.mport.retro.RetrosheetRuntimeException; import org.statmantis.util.CsvUtils; /** * Reader for event log ZIP files * * @author Chad Retz */ public class RetrosheetEventReader extends RetrosheetReader<EventInformation> { private static final Logger logger = LoggerFactory.getLogger(RetrosheetEventReader.class); private final int year; private final String directory; private final RetrosheetContext retroContext; /** * Reader for pulling from URL * * @param year * @param context */ public RetrosheetEventReader(int year, RetrosheetContext context) { this(year, null, context); } /** * Reader from pulling from local file * * @param year * @param directory * @param retroContext */ public RetrosheetEventReader(int year, String directory, RetrosheetContext retroContext) { this.year = year; this.directory = directory; this.retroContext = retroContext; } @Override public EventInformation read() throws IOException { if (year <= 1996) { EventInformation info = readOne(year + "al.zip"); if (info != null) { info.merge(readOne(year + "nl.zip")); } else { info = readOne(year + "nl.zip"); } return info; } else { return readOne(year + "ml.zip"); } } public EventInformation readOne(String name) { try { if (directory != null) { return read(new BufferedInputStream(new FileInputStream(directory + File.separator + name))); } else { HttpClient client = new DefaultHttpClient(); HttpEntity entity = client.execute(new HttpGet("http://www.retrosheet.org/" + year + "/" + name)) .getEntity(); if (entity == null) { return null; } else { return read(new BufferedInputStream(entity.getContent())); } } } catch (Exception e) { throw new RetrosheetRuntimeException("Error reading file " + name, e); } } @Override protected EventInformation read(InputStream stream) throws IOException { ZipInputStream zis = new ZipInputStream(stream); try { EventInformation info = new EventInformation(); ZipEntry entry = zis.getNextEntry(); while (entry != null) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(zis)); if (entry.getName().equals("TEAM" + year)) { readTeamFile(entry.getName(), reader, info); } else if (entry.getName().endsWith(".ROS")) { readRosterFile(entry.getName(), reader, info); } else if (entry.getName().endsWith(".EVA") || entry.getName().endsWith(".EVN") || entry.getName().endsWith(".eba") || entry.getName().endsWith(".ebn")) { readEventFile(entry.getName(), reader, info); } else { throw new RetrosheetRuntimeException("Unknown zip entry: " + entry); } } catch (Exception e) { throw new RetrosheetRuntimeException("Error reading zip entry " + entry.getName(), e); } entry = zis.getNextEntry(); } return info; } finally { try { zis.close(); } catch (Exception e) { //no-op } } } private Roster createBlankRoster(String team) { Roster roster = new Roster(); roster.setPlayers(new ArrayList<Person>()); roster.setTeam(retroContext.getTeams().get(team)); if (roster.getTeam() == null) { throw new RetrosheetRuntimeException("Unable to find team " + team); } roster.setYear(year); return roster; } private void readTeamFile(String name, BufferedReader reader, EventInformation info) throws IOException { List<Map<TeamColumn, String>> lines = CsvUtils.readCsv(TeamColumn.class, reader, false); for (int i = 0; i < lines.size(); i++) { try { Map<TeamColumn, String> line = lines.get(i); String team = line.get(TeamColumn.TEAM_ID); Roster roster = info.getRosters().get(team); if (roster == null) { roster = createBlankRoster(team); info.getRosters().put(roster.getTeam().getRetroId(), roster); } String teamName = line.get(TeamColumn.CITY) + " " + line.get(TeamColumn.NAME); if (!roster.getTeam().getName().equals(teamName)) { List<String> otherNames = roster.getTeam().getOtherNames(); if (otherNames == null || !otherNames.contains(teamName)) { if (logger.isDebugEnabled()) { logger.debug("Team name '" + teamName + "' for " + roster.getTeam() + " not found; adding..."); } if (otherNames == null) { otherNames = new ArrayList<String>(); roster.getTeam().setOtherNames(otherNames); } otherNames.add(teamName); } } } catch (Exception e) { throw new RetrosheetRuntimeException("Error reading line " + i, e); } } } private void readRosterFile(String name, BufferedReader reader, EventInformation info) throws IOException { List<Map<RosterColumn, String>> lines = CsvUtils.readCsv(RosterColumn.class, reader, false); for (int i = 0; i < lines.size(); i++) { try { Map<RosterColumn, String> line = lines.get(i); String team = line.get(RosterColumn.TEAM_ID); Roster roster = info.getRosters().get(team); if (roster == null) { roster = createBlankRoster(team); info.getRosters().put(roster.getTeam().getRetroId(), roster); } Person person = retroContext.getPersons().get(line.get(RosterColumn.PERSON_ID)); if (person == null) { throw new RetrosheetRuntimeException( "Unable to find player " + line.get(RosterColumn.PERSON_ID)); } roster.getPlayers().add(person); } catch (Exception e) { throw new RetrosheetRuntimeException("Error reading line " + i, e); } } } private void readEventFile(String name, BufferedReader reader, EventInformation info) throws IOException { List<String[]> lines = CsvUtils.readCsv(reader, false); GameContext context = new GameContext(retroContext, info); for (int i = 0; i < lines.size(); i++) { try { EventFileUtils.parseLine(lines.get(i), context); } catch (Exception e) { throw new RetrosheetRuntimeException("Error reading line " + i, e); } } } }