package cgeo.geocaching.files; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.gc.GCConnector; import cgeo.geocaching.connector.gc.GCConstants; import cgeo.geocaching.models.Geocache; import cgeo.geocaching.models.Trackable; import cgeo.geocaching.utils.DisposableHandler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; 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.Collection; import java.util.List; import java.util.concurrent.CancellationException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.CharEncoding; abstract class FileParser { /** * Parses caches from input stream. * * @param stream * the input stream * @param progressHandler * for reporting parsing progress (in bytes read from input stream) * @return collection of caches * @throws IOException * if the input stream can't be read * @throws ParserException * if the input stream contains data not matching the file format of the parser */ @NonNull public abstract Collection<Geocache> parse(@NonNull final InputStream stream, @Nullable final DisposableHandler progressHandler) throws IOException, ParserException; /** * Convenience method for parsing a file. */ @NonNull public Collection<Geocache> parse(final File file, final DisposableHandler progressHandler) throws IOException, ParserException { final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file)); try { return parse(stream, progressHandler); } finally { IOUtils.closeQuietly(stream); } } @NonNull protected static StringBuilder readStream(@NonNull final InputStream is, @Nullable final DisposableHandler progressHandler) throws IOException { final StringBuilder buffer = new StringBuilder(); final ProgressInputStream progressInputStream = new ProgressInputStream(is); final BufferedReader input = new BufferedReader(new InputStreamReader(progressInputStream, CharEncoding.UTF_8)); try { String line; while ((line = input.readLine()) != null) { buffer.append(line); showProgressMessage(progressHandler, progressInputStream.getProgress()); } return buffer; } finally { IOUtils.closeQuietly(input); } } protected static void showProgressMessage(@Nullable final DisposableHandler handler, final int bytesRead) { if (handler != null) { if (handler.isDisposed()) { throw new CancellationException(); } handler.sendMessage(handler.obtainMessage(0, bytesRead, 0)); } } protected static void fixCache(final Geocache cache) { final List<Trackable> inventory = cache.getInventory(); cache.setInventoryItems(inventory.size()); final long time = System.currentTimeMillis(); cache.setUpdated(time); cache.setDetailedUpdate(time); // fix potentially bad cache id if (GCConnector.getInstance().equals(ConnectorFactory.getConnector(cache))) { cache.setCacheId(String.valueOf(GCConstants.gccodeToGCId(cache.getGeocode()))); } } }