1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 10:19:33 +02:00

see previous comment

This commit is contained in:
Nikolay Pultsin 2010-10-09 03:58:20 +01:00
parent 87ef3e2063
commit b2f140c612
20 changed files with 231 additions and 265 deletions

View file

@ -285,8 +285,7 @@ public class BookDownloaderService extends Service {
};
final ZLNetworkRequest request = new ZLNetworkRequest(urlString, sslCertificate) {
public String handleStream(URLConnection connection, InputStream inputStream) throws IOException {
public void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
final int updateIntervalMillis = 1000; // FIXME: remove hardcoded time constant
final int fileLength = connection.getContentLength();
@ -299,7 +298,7 @@ public class BookDownloaderService extends Service {
try {
outStream = new FileOutputStream(file);
} catch (FileNotFoundException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_CREATE_FILE, file.getPath());
throw new ZLNetworkException(ZLNetworkErrors.ERROR_CREATE_FILE, file.getPath());
}
try {
final byte[] buffer = new byte[8192];
@ -328,19 +327,19 @@ public class BookDownloaderService extends Service {
} finally {
outStream.close();
}
return null;
}
};
final Thread downloader = new Thread(new Runnable() {
public void run() {
final String err = ZLNetworkManager.Instance().perform(request);
try {
ZLNetworkManager.Instance().perform(request);
} catch (ZLNetworkException e) {
// TODO: show error message to User
final boolean success = (err == null);
if (!success) {
file.delete();
downloadFinishHandler.sendEmptyMessage(0);
}
downloadFinishHandler.sendEmptyMessage(success ? 1 : 0);
downloadFinishHandler.sendEmptyMessage(1);
}
});
downloader.setPriority(Thread.MIN_PRIORITY);

View file

@ -22,13 +22,13 @@ package org.geometerplus.android.fbreader.network;
import android.os.Message;
import android.os.Handler;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.INetworkLink;
import org.geometerplus.fbreader.network.NetworkOperationData;
import org.geometerplus.fbreader.network.NetworkLibraryItem;
abstract class ItemsLoadingRunnable implements Runnable {
private final ItemsLoadingHandler myHandler;
private final long myUpdateInterval; // in milliseconds
@ -83,7 +83,7 @@ abstract class ItemsLoadingRunnable implements Runnable {
}
public abstract String doBefore();
public abstract String doLoading(NetworkOperationData.OnNewItemListener doWithListener);
public abstract void doLoading(NetworkOperationData.OnNewItemListener doWithListener) throws ZLNetworkException;
public abstract String getResourceKey();

View file

@ -30,6 +30,7 @@ import android.view.ContextMenu;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.ui.android.dialogs.ZLAndroidDialogManager;
@ -342,7 +343,6 @@ class NetworkCatalogActions extends NetworkTreeActions {
}
private static class ExpandCatalogRunnable extends ItemsLoadingRunnable {
private final NetworkCatalogTree myTree;
private final boolean myCheckAuthentication;
private final boolean myResumeNotLoad;
@ -380,11 +380,13 @@ class NetworkCatalogActions extends NetworkTreeActions {
return null;
}
public String doLoading(NetworkOperationData.OnNewItemListener doWithListener) {
@Override
public void doLoading(NetworkOperationData.OnNewItemListener doWithListener) throws ZLNetworkException {
if (myResumeNotLoad) {
return myTree.Item.resumeLoading(doWithListener);
myTree.Item.resumeLoading(doWithListener);
} else {
myTree.Item.loadChildren(doWithListener);
}
return myTree.Item.loadChildren(doWithListener);
}
}

View file

@ -29,6 +29,7 @@ import android.os.Bundle;
import android.content.Intent;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.*;
@ -140,8 +141,8 @@ public class NetworkSearchActivity extends Activity {
return null;
}
public String doLoading(NetworkOperationData.OnNewItemListener doWithListener) {
return NetworkLibrary.Instance().simpleSearch(myPattern, doWithListener);
public void doLoading(NetworkOperationData.OnNewItemListener doWithListener) throws ZLNetworkException {
NetworkLibrary.Instance().simpleSearch(myPattern, doWithListener);
}
}

View file

@ -19,6 +19,8 @@
package org.geometerplus.fbreader.network;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
public interface ICustomNetworkLink extends INetworkLink {
public static final int INVALID_ID = -1;
@ -41,7 +43,7 @@ public interface ICustomNetworkLink extends INetworkLink {
void setLink(String urlKey, String url);
void removeLink(String urlKey);
String reloadInfo();
void reloadInfo() throws ZLNetworkException;
// returns true if next methods have changed link's data:
// setSiteName, setTitle, setSummary, setIcon, setLink, removeLink

View file

@ -22,7 +22,7 @@ package org.geometerplus.fbreader.network;
import java.util.*;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
public abstract class NetworkCatalogItem extends NetworkLibraryItem {
@ -90,14 +90,14 @@ public abstract class NetworkCatalogItem extends NetworkLibraryItem {
URLByType = new TreeMap<Integer, String>(urlByType);
}
public abstract String loadChildren(NetworkOperationData.OnNewItemListener listener); // returns Error Message
public abstract void loadChildren(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException;
public boolean supportsResumeLoading() {
return false;
}
public String resumeLoading(NetworkOperationData.OnNewItemListener listener) { // returns Error Message
return NetworkErrors.errorMessage(NetworkErrors.ERROR_UNSUPPORTED_OPERATION);
public void resumeLoading(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException {
throw new ZLNetworkException(NetworkErrors.ERROR_UNSUPPORTED_OPERATION);
}

View file

@ -23,8 +23,9 @@ import java.util.*;
import org.geometerplus.zlibrary.core.util.ZLNetworkUtil;
import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.zlibrary.core.network.ZLNetworkManager;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.fbreader.tree.FBTree;
import org.geometerplus.fbreader.network.tree.*;
@ -226,20 +227,20 @@ public class NetworkLibrary {
myLinks = new CompositeList(linksList, new LinksComparator());
}
public String initialize() {
public void initialize() throws ZLNetworkException {
final LinksComparator comparator = new LinksComparator();
final String error = OPDSLinkReader.loadOPDSLinks(OPDSLinkReader.CACHE_LOAD, new OnNewLinkListener() {
try {
OPDSLinkReader.loadOPDSLinks(OPDSLinkReader.CACHE_LOAD, new OnNewLinkListener() {
public void onNewLink(INetworkLink link) {
addLinkInternal(myLoadedLinks, link, comparator);
}
});
if (error != null) {
} catch (ZLNetworkException e) {
synchronized (myLinks) {
myLoadedLinks.clear();
}
return error;
throw e;
}
NetworkDatabase.Instance().loadCustomLinks(
@ -273,8 +274,6 @@ public class NetworkLibrary {
new ATOMUpdated(2012, 2, 15, 23, 40, 1, 0, 3, 30));
testDate(new ATOMUpdated(2012, 2, 15, 23, 40, 0, 0.001f, 3, 30),
new ATOMUpdated(2012, 2, 15, 23, 40, 0, 0, 3, 30));*/
return null;
}
/*private void testDate(ATOMDateConstruct date1, ATOMDateConstruct date2) {
@ -292,25 +291,29 @@ public class NetworkLibrary {
private Object myBackgroundLock = new Object();
// This method must be called from background thread
public String runBackgroundUpdate(boolean clearCache) {
public void runBackgroundUpdate(boolean clearCache) throws ZLNetworkException {
synchronized (myBackgroundLock) {
myBackgroundLinks = new ArrayList<INetworkLink>();
final int cacheMode = clearCache ? OPDSLinkReader.CACHE_CLEAR : OPDSLinkReader.CACHE_UPDATE;
final String error = OPDSLinkReader.loadOPDSLinks(cacheMode, new OnNewLinkListener() {
try {
OPDSLinkReader.loadOPDSLinks(cacheMode, new OnNewLinkListener() {
public void onNewLink(INetworkLink link) {
myBackgroundLinks.add(link);
}
});
if (error != null || myBackgroundLinks.isEmpty()) {
} catch (ZLNetworkException e) {
myBackgroundLinks = null;
}
throw e;
} finally {
if (myBackgroundLinks != null) {
if (myBackgroundLinks.isEmpty()) {
myBackgroundLinks = null;
} else {
Collections.sort(myBackgroundLinks, new LinksComparator());
}
return error;
}
}
}
}

View file

@ -25,25 +25,9 @@ import org.geometerplus.fbreader.network.NetworkErrors;
class LitResAuthenticationXMLReader extends ZLXMLReaderAdapter {
public final String HostName;
private String myErrorMessage;
public LitResAuthenticationXMLReader(String hostName) {
HostName = hostName;
}
protected void setErrorCode(String code) {
myErrorMessage = NetworkErrors.errorMessage(code);
}
protected void setErrorCode(String code, String arg) {
myErrorMessage = NetworkErrors.errorMessage(code, arg);
}
public String getErrorMessage() {
return myErrorMessage;
}
}

View file

@ -22,10 +22,10 @@ package org.geometerplus.fbreader.network.authentication.litres;
import java.util.*;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.*;
public class LitResBookshelfItem extends NetworkCatalogItem {
private boolean myForceReload;
@ -49,15 +49,16 @@ public class LitResBookshelfItem extends NetworkCatalogItem {
}
@Override
public String loadChildren(NetworkOperationData.OnNewItemListener listener) {
public void loadChildren(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException {
LitResAuthenticationManager mgr = (LitResAuthenticationManager) Link.authenticationManager();
if (mgr.isAuthorised(true).Status == ZLBoolean3.B3_FALSE) {
return NetworkErrors.errorMessage(NetworkErrors.ERROR_AUTHENTICATION_FAILED);
throw new ZLNetworkException(NetworkErrors.ERROR_AUTHENTICATION_FAILED);
}
String error = null;
try {
if (myForceReload) {
error = mgr.reloadPurchasedBooks();
mgr.reloadPurchasedBooks();
}
} finally {
myForceReload = true;
// TODO: implement asynchronous loading
LinkedList<NetworkLibraryItem> children = new LinkedList<NetworkLibraryItem>();
@ -67,6 +68,6 @@ public class LitResBookshelfItem extends NetworkCatalogItem {
listener.onNewItem(Link, item);
}
listener.commitItems(Link);
return error;
}
}
}

View file

@ -20,12 +20,11 @@
package org.geometerplus.fbreader.network.authentication.litres;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.NetworkErrors;
class LitResLoginXMLReader extends LitResAuthenticationXMLReader {
private static final String TAG_AUTHORIZATION_OK = "catalit-authorization-ok";
private static final String TAG_AUTHORIZATION_FAILED = "catalit-authorization-failed";
@ -41,13 +40,13 @@ class LitResLoginXMLReader extends LitResAuthenticationXMLReader {
public boolean startElementHandler(String tag, ZLStringMap attributes) {
tag = tag.toLowerCase().intern();
if (TAG_AUTHORIZATION_FAILED == tag) {
setErrorCode(NetworkErrors.ERROR_AUTHENTICATION_FAILED);
throw new ZLNetworkException(NetworkErrors.ERROR_AUTHENTICATION_FAILED);
} else if (TAG_AUTHORIZATION_OK == tag) {
FirstName = attributes.getValue("first-name");
LastName = attributes.getValue("first-name");
Sid = attributes.getValue("sid");
} else {
setErrorCode(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
throw new ZLNetworkException(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
}
return true;
}

View file

@ -23,11 +23,10 @@ import java.io.InputStream;
import java.io.IOException;
import java.net.URLConnection;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
class LitResNetworkRequest extends ZLNetworkRequest {
public final LitResAuthenticationXMLReader Reader;
public LitResNetworkRequest(String url, String sslCertificate, LitResAuthenticationXMLReader reader) {
@ -36,8 +35,7 @@ class LitResNetworkRequest extends ZLNetworkRequest {
}
@Override
public String handleStream(URLConnection connection, InputStream inputStream) throws IOException {
public void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
Reader.read(inputStream);
return Reader.getErrorMessage();
}
}

View file

@ -20,12 +20,11 @@
package org.geometerplus.fbreader.network.authentication.litres;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.NetworkErrors;
class LitResPasswordRecoveryXMLReader extends LitResAuthenticationXMLReader {
private static final String TAG_PASSWORD_RECOVERY_OK = "catalit-pass-recover-ok";
private static final String TAG_PASSWORD_RECOVERY_FAILED = "catalit-pass-recover-failed";
@ -39,16 +38,16 @@ class LitResPasswordRecoveryXMLReader extends LitResAuthenticationXMLReader {
if (TAG_PASSWORD_RECOVERY_FAILED == tag) {
final String error = attributes.getValue("error");
if ("1".equals(error)) {
setErrorCode(NetworkErrors.ERROR_NO_USER_EMAIL);
throw new ZLNetworkException(NetworkErrors.ERROR_NO_USER_EMAIL);
} else if ("2".equals(error)) {
setErrorCode(NetworkErrors.ERROR_EMAIL_WAS_NOT_SPECIFIED);
throw new ZLNetworkException(NetworkErrors.ERROR_EMAIL_WAS_NOT_SPECIFIED);
} else {
setErrorCode(NetworkErrors.ERROR_INTERNAL);
throw new ZLNetworkException(NetworkErrors.ERROR_INTERNAL);
}
} else if (TAG_PASSWORD_RECOVERY_OK == tag) {
// NOP
} else {
setErrorCode(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
throw new ZLNetworkException(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
}
return true;
}

View file

@ -20,12 +20,11 @@
package org.geometerplus.fbreader.network.authentication.litres;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.NetworkErrors;
class LitResPurchaseXMLReader extends LitResAuthenticationXMLReader {
private static final String TAG_AUTHORIZATION_FAILED = "catalit-authorization-failed";
private static final String TAG_PURCHASE_OK = "catalit-purchase-ok";
private static final String TAG_PURCHASE_FAILED = "catalit-purchase-failed";
@ -41,7 +40,7 @@ class LitResPurchaseXMLReader extends LitResAuthenticationXMLReader {
public boolean startElementHandler(String tag, ZLStringMap attributes) {
tag = tag.toLowerCase().intern();
if (TAG_AUTHORIZATION_FAILED == tag) {
setErrorCode(NetworkErrors.ERROR_AUTHENTICATION_FAILED);
throw new ZLNetworkException(NetworkErrors.ERROR_AUTHENTICATION_FAILED);
} else {
Account = attributes.getValue("account");
BookId = attributes.getValue("art");
@ -50,16 +49,16 @@ class LitResPurchaseXMLReader extends LitResAuthenticationXMLReader {
} else if (TAG_PURCHASE_FAILED == tag) {
final String error = attributes.getValue("error");
if ("1".equals(error)) {
setErrorCode(NetworkErrors.ERROR_PURCHASE_NOT_ENOUGH_MONEY);
throw new ZLNetworkException(NetworkErrors.ERROR_PURCHASE_NOT_ENOUGH_MONEY);
} else if ("2".equals(error)) {
setErrorCode(NetworkErrors.ERROR_PURCHASE_MISSING_BOOK);
throw new ZLNetworkException(NetworkErrors.ERROR_PURCHASE_MISSING_BOOK);
} else if ("3".equals(error)) {
setErrorCode(NetworkErrors.ERROR_PURCHASE_ALREADY_PURCHASED);
throw new ZLNetworkException(NetworkErrors.ERROR_PURCHASE_ALREADY_PURCHASED);
} else {
setErrorCode(NetworkErrors.ERROR_INTERNAL);
throw new ZLNetworkException(NetworkErrors.ERROR_INTERNAL);
}
} else {
setErrorCode(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
throw new ZLNetworkException(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
}
}
return true;

View file

@ -20,12 +20,11 @@
package org.geometerplus.fbreader.network.authentication.litres;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.network.NetworkErrors;
class LitResRegisterUserXMLReader extends LitResAuthenticationXMLReader {
private static final String TAG_AUTHORIZATION_OK = "catalit-authorization-ok";
private static final String TAG_REGISTRATION_FAILED = "catalit-registration-failed";
@ -41,22 +40,22 @@ class LitResRegisterUserXMLReader extends LitResAuthenticationXMLReader {
if (TAG_REGISTRATION_FAILED == tag) {
final String error = attributes.getValue("error");
if ("1".equals(error)) {
setErrorCode(NetworkErrors.ERROR_LOGIN_ALREADY_TAKEN);
throw new ZLNetworkException(NetworkErrors.ERROR_LOGIN_ALREADY_TAKEN);
} else if ("2".equals(error)) {
setErrorCode(NetworkErrors.ERROR_LOGIN_WAS_NOT_SPECIFIED);
throw new ZLNetworkException(NetworkErrors.ERROR_LOGIN_WAS_NOT_SPECIFIED);
} else if ("3".equals(error)) {
setErrorCode(NetworkErrors.ERROR_PASSWORD_WAS_NOT_SPECIFIED);
throw new ZLNetworkException(NetworkErrors.ERROR_PASSWORD_WAS_NOT_SPECIFIED);
} else if ("4".equals(error)) {
setErrorCode(NetworkErrors.ERROR_INVALID_EMAIL);
throw new ZLNetworkException(NetworkErrors.ERROR_INVALID_EMAIL);
} else if ("5".equals(error)) {
setErrorCode(NetworkErrors.ERROR_TOO_MANY_REGISTRATIONS);
throw new ZLNetworkException(NetworkErrors.ERROR_TOO_MANY_REGISTRATIONS);
} else {
setErrorCode(NetworkErrors.ERROR_INTERNAL);
throw new ZLNetworkException(NetworkErrors.ERROR_INTERNAL);
}
} else if (TAG_AUTHORIZATION_OK == tag) {
Sid = attributes.getValue("sid");
} else {
setErrorCode(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
throw new ZLNetworkException(NetworkErrors.ERROR_SOMETHING_WRONG, HostName);
}
return true;
}

View file

@ -22,8 +22,9 @@ package org.geometerplus.fbreader.network.opds;
import java.util.Map;
import java.util.HashSet;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.zlibrary.core.network.ZLNetworkManager;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.fbreader.network.*;
@ -51,24 +52,24 @@ class OPDSCatalogItem extends NetworkCatalogItem {
super(link, title, summary, cover, urlByType, visibility, catalogType);
}
private String doLoadChildren(NetworkOperationData.OnNewItemListener listener,
ZLNetworkRequest networkRequest) {
private void doLoadChildren(NetworkOperationData.OnNewItemListener listener,
ZLNetworkRequest networkRequest) throws ZLNetworkException {
while (networkRequest != null) {
final String errorMessage = ZLNetworkManager.Instance().perform(networkRequest);
if (errorMessage != null) {
try {
ZLNetworkManager.Instance().perform(networkRequest);
} catch (ZLNetworkException e) {
myLoadingState = null;
return errorMessage;
throw e;
}
if (listener.confirmInterrupt()) {
return null;
return;
}
networkRequest = myLoadingState.resume();
}
return null;
}
@Override
public final String loadChildren(NetworkOperationData.OnNewItemListener listener) {
public final void loadChildren(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException {
OPDSNetworkLink opdsLink = (OPDSNetworkLink) Link;
myLoadingState = opdsLink.createOperationData(Link, listener);
@ -76,7 +77,7 @@ class OPDSCatalogItem extends NetworkCatalogItem {
ZLNetworkRequest networkRequest =
opdsLink.createNetworkData(URLByType.get(URL_CATALOG), myLoadingState);
return doLoadChildren(listener, networkRequest);
doLoadChildren(listener, networkRequest);
}
@Override
@ -85,12 +86,11 @@ class OPDSCatalogItem extends NetworkCatalogItem {
}
@Override
public final String resumeLoading(NetworkOperationData.OnNewItemListener listener) {
if (myLoadingState == null) {
return null;
}
public final void resumeLoading(NetworkOperationData.OnNewItemListener listener) throws ZLNetworkException {
if (myLoadingState != null) {
myLoadingState.Listener = listener;
ZLNetworkRequest networkRequest = myLoadingState.resume();
return doLoadChildren(listener, networkRequest);
doLoadChildren(listener, networkRequest);
}
}
}

View file

@ -25,6 +25,7 @@ import java.net.URLConnection;
import java.util.*;
import org.geometerplus.zlibrary.core.network.ZLNetworkManager;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.zlibrary.core.util.ZLMiscUtil;
@ -109,21 +110,23 @@ class OPDSCustomLink extends OPDSNetworkLink implements ICustomNetworkLink {
}
public String reloadInfo() {
public void reloadInfo() throws ZLNetworkException {
final LinkedList<String> opensearchDescriptionURLs = new LinkedList<String>();
final List<OpenSearchDescription> descriptions = Collections.synchronizedList(new LinkedList<OpenSearchDescription>());
String err = ZLNetworkManager.Instance().perform(new ZLNetworkRequest(getLink(INetworkLink.URL_MAIN)) {
ZLNetworkException error = null;
try {
ZLNetworkManager.Instance().perform(new ZLNetworkRequest(getLink(INetworkLink.URL_MAIN)) {
@Override
public String handleStream(URLConnection connection, InputStream inputStream) throws IOException {
public void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
final CatalogInfoReader info = new CatalogInfoReader(URL, OPDSCustomLink.this, opensearchDescriptionURLs);
new OPDSXMLReader(info).read(inputStream);
if (!info.FeedStarted) {
return NetworkErrors.errorMessage("notAnOPDS");
throw new ZLNetworkException("notAnOPDS");
}
if (info.Title == null) {
return NetworkErrors.errorMessage("noRequiredInformation");
throw new ZLNetworkException("noRequiredInformation");
}
myTitle = info.Title;
if (info.Icon != null) {
@ -135,9 +138,11 @@ class OPDSCustomLink extends OPDSNetworkLink implements ICustomNetworkLink {
if (info.DirectOpenSearchDescription != null) {
descriptions.add(info.DirectOpenSearchDescription);
}
return null;
}
});
} catch (ZLNetworkException e) {
error = e;
}
// TODO: Use ALL available descriptions and not only Direct
if (descriptions.isEmpty() && !opensearchDescriptionURLs.isEmpty()) {
@ -145,15 +150,17 @@ class OPDSCustomLink extends OPDSNetworkLink implements ICustomNetworkLink {
for (String url: opensearchDescriptionURLs) {
requests.add(new ZLNetworkRequest(url) {
@Override
public String handleStream(URLConnection connection, InputStream inputStream) throws IOException {
public void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
new OpenSearchXMLReader(URL, descriptions, 20).read(inputStream);
return null;
}
});
}
final String err2 = ZLNetworkManager.Instance().perform(requests);
if (err == null) {
err = err2;
try {
ZLNetworkManager.Instance().perform(requests);
} catch (ZLNetworkException e) {
if (error == null) {
error = e;
}
}
}
@ -161,6 +168,8 @@ class OPDSCustomLink extends OPDSNetworkLink implements ICustomNetworkLink {
// TODO: May be do not use '%s'??? Use Description instead??? (this needs to rewrite SEARCH engine logic a little)
setLink(URL_SEARCH, descriptions.get(0).makeQuery("%s"));
}
return err;
if (error != null) {
throw error;
}
}
}

View file

@ -27,6 +27,7 @@ import java.util.Map;
import java.net.URL;
import org.geometerplus.zlibrary.core.network.ZLNetworkManager;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.fbreader.Paths;
import org.geometerplus.fbreader.network.*;
@ -54,23 +55,23 @@ public class OPDSLinkReader {
public static final int CACHE_UPDATE = 1;
public static final int CACHE_CLEAR = 2;
public static String loadOPDSLinks(int cacheMode, final NetworkLibrary.OnNewLinkListener listener) {
public static void loadOPDSLinks(int cacheMode, final NetworkLibrary.OnNewLinkListener listener) throws ZLNetworkException {
final File dirFile = new File(Paths.networkCacheDirectory());
if (!dirFile.exists() && !dirFile.mkdirs()) {
try {
// Hmm, I'm not sure this solution is good enough; it uses java.net.URL directly instead of ZLNetworkManager
// -- NP
new OPDSLinkXMLReader(listener, null).read(new URL(CATALOGS_URL).openStream());
return null;
return;
} catch (Exception e) {
return NetworkErrors.errorMessage("cacheDirectoryError");
throw new ZLNetworkException("cacheDirectoryError");
}
}
final String fileName = "fbreader_catalogs-"
+ CATALOGS_URL.substring(CATALOGS_URL.lastIndexOf(File.separator) + 1);
boolean goodCache = false;
boolean cacheIsGood = false;
File oldCache = null;
ATOMUpdated cacheUpdatedTime = null;
final File catalogsFile = new File(dirFile, fileName);
@ -80,7 +81,7 @@ public class OPDSLinkReader {
final long diff = System.currentTimeMillis() - catalogsFile.lastModified();
final long valid = 7 * 24 * 60 * 60 * 1000; // one week in milliseconds; FIXME: hardcoded const
if (diff >= 0 && diff <= valid) {
return null;
return;
}
/* FALLTHROUGH */
case CACHE_CLEAR:
@ -100,7 +101,7 @@ public class OPDSLinkReader {
}
break;
case CACHE_LOAD:
goodCache = true;
cacheIsGood = true;
break;
default:
throw new IllegalArgumentException("Invalid cacheMode value (" + cacheMode
@ -108,30 +109,31 @@ public class OPDSLinkReader {
}
}
String error = null;
if (!goodCache) {
error = ZLNetworkManager.Instance().downloadToFile(CATALOGS_URL, catalogsFile);
}
if (error != null) {
if (!cacheIsGood) {
try {
ZLNetworkManager.Instance().downloadToFile(CATALOGS_URL, catalogsFile);
} catch (ZLNetworkException e) {
if (oldCache == null) {
return error;
throw e;
}
catalogsFile.delete();
if (!oldCache.renameTo(catalogsFile)) {
oldCache.delete();
return error;
oldCache = null;
throw e;
}
} else if (oldCache != null) {
} finally {
if (oldCache != null) {
oldCache.delete();
oldCache = null;
}
}
}
try {
new OPDSLinkXMLReader(listener, cacheUpdatedTime).read(new FileInputStream(catalogsFile));
} catch (FileNotFoundException e) {
throw new RuntimeException("That's impossible!!!", e);
}
return null;
}
}

View file

@ -26,6 +26,7 @@ import java.io.IOException;
import org.geometerplus.zlibrary.core.util.ZLMiscUtil;
import org.geometerplus.zlibrary.core.util.ZLNetworkUtil;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.fbreader.network.*;
@ -89,9 +90,9 @@ class OPDSNetworkLink extends AbstractNetworkLink {
url = rewriteUrl(url, false);
return new ZLNetworkRequest(url) {
@Override
public String handleStream(URLConnection connection, InputStream inputStream) throws IOException {
public void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
if (result.Listener.confirmInterrupt()) {
return null;
return;
}
new OPDSXMLReader(
@ -110,7 +111,6 @@ class OPDSNetworkLink extends AbstractNetworkLink {
} else {
result.Listener.commitItems(OPDSNetworkLink.this);
}
return null;
}
};
}

View file

@ -41,20 +41,7 @@ public class ZLNetworkManager {
return ourManager;
}
private String doBeforeRequest(ZLNetworkRequest request) {
final String err = request.doBefore();
if (err != null) {
return err;
}
/*if (request.isInstanceOf(ZLNetworkPostRequest::TYPE_ID)) {
return doBeforePostRequest((ZLNetworkPostRequest &) request);
}*/
return null;
}
private String setCommonHTTPOptions(ZLNetworkRequest request, HttpURLConnection httpConnection) {
private void setCommonHTTPOptions(ZLNetworkRequest request, HttpURLConnection httpConnection) throws ZLNetworkException {
httpConnection.setInstanceFollowRedirects(request.FollowRedirects);
httpConnection.setConnectTimeout(15000); // FIXME: hardcoded timeout value!!!
httpConnection.setReadTimeout(30000); // FIXME: hardcoded timeout value!!!
@ -69,7 +56,7 @@ public class ZLNetworkManager {
ZLResourceFile file = ZLResourceFile.createResourceFile(request.SSLCertificate);
stream = file.getInputStream();
} catch (IOException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_BAD_FILE, request.SSLCertificate);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_BAD_FILE, request.SSLCertificate);
}
try {
TrustManager[] managers = new TrustManager[] { new ZLX509TrustManager(stream) };
@ -77,13 +64,13 @@ public class ZLNetworkManager {
context.init(null, managers, null);
httpsConnection.setSSLSocketFactory(context.getSocketFactory());
} catch (CertificateExpiredException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_EXPIRED, request.SSLCertificate);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_EXPIRED, request.SSLCertificate);
} catch (CertificateNotYetValidException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_NOT_YET_VALID, request.SSLCertificate);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_NOT_YET_VALID, request.SSLCertificate);
} catch (CertificateException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_BAD_FILE, request.SSLCertificate);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_BAD_FILE, request.SSLCertificate);
} catch (GeneralSecurityException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_SUBSYSTEM);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_SUBSYSTEM);
} finally {
try {
stream.close();
@ -93,100 +80,85 @@ public class ZLNetworkManager {
}
}
// TODO: handle Authentication
return null;
}
public String perform(ZLNetworkRequest request) {
public void perform(ZLNetworkRequest request) throws ZLNetworkException {
boolean success = false;
try {
final String error = doBeforeRequest(request);
if (error != null) {
return error;
}
request.doBefore();
HttpURLConnection httpConnection = null;
int response = -1;
for (int retryCounter = 0; retryCounter < 3 && response == -1; ++retryCounter) {
final URL url = new URL(request.URL);
final URLConnection connection = url.openConnection();
if (!(connection instanceof HttpURLConnection)) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_UNSUPPORTED_PROTOCOL);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_UNSUPPORTED_PROTOCOL);
}
httpConnection = (HttpURLConnection) connection;
String err = setCommonHTTPOptions(request, httpConnection);
if (err != null) {
return err;
}
setCommonHTTPOptions(request, httpConnection);
httpConnection.connect();
response = httpConnection.getResponseCode();
}
if (response == HttpURLConnection.HTTP_OK) {
InputStream stream = httpConnection.getInputStream();
try {
final String err = request.doHandleStream(httpConnection, stream);
if (err != null) {
return err;
}
request.doHandleStream(httpConnection, stream);
} finally {
stream.close();
}
success = true;
} else {
if (response == HttpURLConnection.HTTP_UNAUTHORIZED) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_AUTHENTICATION_FAILED);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_AUTHENTICATION_FAILED);
} else {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SOMETHING_WRONG, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SOMETHING_WRONG, ZLNetworkUtil.hostFromUrl(request.URL));
}
}
} catch (SSLHandshakeException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_CONNECT, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_CONNECT, ZLNetworkUtil.hostFromUrl(request.URL));
} catch (SSLKeyException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_BAD_KEY, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_BAD_KEY, ZLNetworkUtil.hostFromUrl(request.URL));
} catch (SSLPeerUnverifiedException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_PEER_UNVERIFIED, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_PEER_UNVERIFIED, ZLNetworkUtil.hostFromUrl(request.URL));
} catch (SSLProtocolException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_PROTOCOL_ERROR);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_PROTOCOL_ERROR);
} catch (SSLException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SSL_SUBSYSTEM);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SSL_SUBSYSTEM);
} catch (ConnectException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_CONNECTION_REFUSED, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_CONNECTION_REFUSED, ZLNetworkUtil.hostFromUrl(request.URL));
} catch (NoRouteToHostException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_HOST_CANNOT_BE_REACHED, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_HOST_CANNOT_BE_REACHED, ZLNetworkUtil.hostFromUrl(request.URL));
} catch (UnknownHostException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_RESOLVE_HOST, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_RESOLVE_HOST, ZLNetworkUtil.hostFromUrl(request.URL));
} catch (MalformedURLException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_INVALID_URL);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_INVALID_URL);
} catch (SocketTimeoutException ex) {
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_TIMEOUT);
throw new ZLNetworkException(ZLNetworkErrors.ERROR_TIMEOUT);
} catch (IOException ex) {
ex.printStackTrace();
return ZLNetworkErrors.errorMessage(ZLNetworkErrors.ERROR_SOMETHING_WRONG, ZLNetworkUtil.hostFromUrl(request.URL));
throw new ZLNetworkException(ZLNetworkErrors.ERROR_SOMETHING_WRONG, ZLNetworkUtil.hostFromUrl(request.URL));
} finally {
final String err = request.doAfter(success);
if (success && err != null) {
return err;
request.doAfter(success);
}
}
return null;
}
public String perform(List<ZLNetworkRequest> requests) {
public void perform(List<ZLNetworkRequest> requests) throws ZLNetworkException {
if (requests.size() == 0) {
return "";
throw new ZLNetworkException("");
}
if (requests.size() == 1) {
return perform(requests.get(0));
perform(requests.get(0));
}
HashSet<String> errors = new HashSet<String>();
// TODO: implement concurrent execution !!!
for (ZLNetworkRequest r: requests) {
final String e = perform(r);
if (e != null && !errors.contains(e)) {
errors.add(e);
try {
perform(r);
} catch (ZLNetworkException e) {
errors.add(e.getMessage());
}
}
if (errors.size() == 0) {
return null;
}
if (errors.size() > 0) {
StringBuilder message = new StringBuilder();
for (String e : errors) {
if (message.length() != 0) {
@ -194,17 +166,18 @@ public class ZLNetworkManager {
}
message.append(e);
}
return message.toString();
throw new ZLNetworkException(true, message.toString());
}
}
public final String downloadToFile(String url, final File outFile) {
return downloadToFile(url, outFile, 8192);
public final void downloadToFile(String url, final File outFile) throws ZLNetworkException {
downloadToFile(url, outFile, 8192);
}
public final String downloadToFile(String url, final File outFile, final int bufferSize) {
return perform(new ZLNetworkRequest(url) {
public String handleStream(URLConnection connection, InputStream inputStream) throws IOException {
public final void downloadToFile(String url, final File outFile, final int bufferSize) throws ZLNetworkException {
perform(new ZLNetworkRequest(url) {
public void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
OutputStream outStream = new FileOutputStream(outFile);
try {
final byte[] buffer = new byte[bufferSize];
@ -218,7 +191,6 @@ public class ZLNetworkManager {
} finally {
outStream.close();
}
return null;
}
});
}

View file

@ -50,12 +50,10 @@ public abstract class ZLNetworkRequest {
SSLCertificate = sslCertificate;
}
// callbacks return error messages
public String doBefore() {
return null;
public void doBefore() throws ZLNetworkException {
}
String doHandleStream(URLConnection connection, InputStream inputStream) throws IOException {
void doHandleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException {
String encoding = connection.getContentEncoding();
if (encoding != null) {
encoding = encoding.toLowerCase();
@ -63,12 +61,11 @@ public abstract class ZLNetworkRequest {
inputStream = new GZIPInputStream(inputStream);
}
}
return handleStream(connection, inputStream);
handleStream(connection, inputStream);
}
public abstract String handleStream(URLConnection connection, InputStream inputStream) throws IOException;
public abstract void handleStream(URLConnection connection, InputStream inputStream) throws IOException, ZLNetworkException;
public String doAfter(boolean success) { // returned error message is ignored when `success == false`
return null;
public void doAfter(boolean success) throws ZLNetworkException {
}
}