/* * Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.fbreader.network; import java.io.File; import java.net.URI; import org.geometerplus.fbreader.Paths; public class BookReference { public interface Type { int UNKNOWN = 0; // Unknown reference type int DOWNLOAD_FULL = 1; // reference for download full version of the book int DOWNLOAD_FULL_CONDITIONAL = 2; // reference for download full version of the book, useful only when book is bought int DOWNLOAD_DEMO = 3; // reference for downloading demo version of the book int DOWNLOAD_FULL_OR_DEMO = 4; // reference for downloading unknown version of the book int BUY = 5; // reference for buying the book (useful only when authentication is supported) int BUY_IN_BROWSER = 6; // reference to the site page, when it is possible to buy the book } // resolvedReferenceType -- reference type without any ambiguity (for example, DOWNLOAD_FULL_OR_DEMO is ambiguous) public interface Format { int NONE = 0; int MOBIPOCKET = 1; int FB2_ZIP = 2; int EPUB = 3; } public final String URL; public final int BookFormat; public final int ReferenceType; public BookReference(String url, int format, int type) { URL = url; BookFormat = format; ReferenceType = type; } // returns clean URL without any account/user-specific parts public String cleanURL() { return URL; } private static final String TOESCAPE = "<>:\"|?*\\"; public static String makeBookFileName(String url, int format, int resolvedReferenceType) { URI uri; try { uri = new URI(url); } catch (java.net.URISyntaxException ex) { return null; } String host = uri.getHost(); StringBuilder path = new StringBuilder(host); if (host.startsWith("www.")) { path.delete(0, 4); } path.insert(0, File.separator); if (resolvedReferenceType == Type.DOWNLOAD_DEMO) { path.insert(0, "Demos"); path.insert(0, File.separator); } path.insert(0, Paths.BooksDirectoryOption().getValue()); int index = path.length(); path.append(uri.getPath()); int nameIndex = index; while (index < path.length()) { char ch = path.charAt(index); if (TOESCAPE.indexOf(ch) != -1) { path.setCharAt(index, '_'); } if (ch == '/') { if (index + 1 == path.length()) { path.deleteCharAt(index); } else { path.setCharAt(index, File.separatorChar); nameIndex = index + 1; } } ++index; } String ext = null; switch (format) { case Format.EPUB: ext = ".epub"; break; case Format.MOBIPOCKET: ext = ".mobi"; break; case Format.FB2_ZIP: ext = ".fb2.zip"; break; } if (ext == null) { int j = path.indexOf(".", nameIndex); // using not lastIndexOf to preserve extensions like `.fb2.zip` if (j != -1) { ext = path.substring(j); path.delete(j, path.length()); } else { return null; } } else if (path.length() > ext.length() && path.substring(path.length() - ext.length()).equals(ext)) { path.delete(path.length() - ext.length(), path.length()); } String query = uri.getQuery(); if (query != null) { index = 0; while (index < query.length()) { int j = query.indexOf("&", index); if (j == -1) { j = query.length(); } String param = query.substring(index, j); if (!param.startsWith("username=") && !param.startsWith("password=") && !param.endsWith("=")) { int k = path.length(); path.append("_").append(param); while (k < path.length()) { char ch = path.charAt(k); if (TOESCAPE.indexOf(ch) != -1 || ch == '/') { path.setCharAt(k, '_'); } ++k; } } index = j + 1; } } return path.append(ext).toString(); } public final String makeBookFileName(int resolvedReferenceType) { return makeBookFileName(cleanURL(), BookFormat, resolvedReferenceType); } public final String localCopyFileName(int resolvedReferenceType) { String fileName = makeBookFileName(resolvedReferenceType); if (fileName != null && new File(fileName).exists()) { return fileName; } return null; } public String toString() { return "BookReference[type=" + ReferenceType + ";format=" + BookFormat + ";URL=" + URL + "]"; } }