org.statmantis.mport.retro.event.RetrosheetEventReader.java Source code

Java tutorial

Introduction

Here is the source code for org.statmantis.mport.retro.event.RetrosheetEventReader.java

Source

/*
 * 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);
            }
        }
    }
}