mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 02:39:23 +02:00
New OPDS.XML DTD and Catalog loading changes
git-svn-id: https://only.mawhrin.net/repos/FBReaderJ/trunk@1619 6a642e6f-84f6-412e-ac94-c4a38d5a04b0
This commit is contained in:
parent
a2719f033b
commit
903eded8f7
25 changed files with 250 additions and 31 deletions
|
@ -10,8 +10,7 @@ DONE сделать SeekBar (как в ветке alex) в пункте Navigate
|
|||
|
||||
DONE каталог должен иметь не 2 состояния (загружен/не загружен), а загружен полностью/не полностью/не загружен:
|
||||
в случае загрузки "не полностью" при повторном открытии продолжать загрузку с точки, где прервались (для тех каталогов, что поделены на куски по 20 книг)
|
||||
** по-умолчанию сделать отбрасывание элементов недогруженных страниц
|
||||
(плюс свойство OPDSLink'ов, подтверждающее стабильность идентификаторов)
|
||||
DONE по-умолчанию сделать отбрасывание элементов недогруженных страниц (плюс свойство OPDSLink'ов hasStableIdentifiers)
|
||||
* 3 иконки в верхнем-правом углу для книжек
|
||||
|
||||
DONE регистрация новых пользователей -- в диалоге authentication
|
||||
|
|
56
data/network/catalog.dtd
Normal file
56
data/network/catalog.dtd
Normal file
|
@ -0,0 +1,56 @@
|
|||
<!ELEMENT catalog (site,title,summary?,link+,advancedSearch?,relationAliases?,feeds?,authentication?,urlRewritingRules?,icon)>
|
||||
<!ATTLIST catalog
|
||||
type (opds) #REQUIRED
|
||||
hasStableIdentifiers (true|false) "false"
|
||||
>
|
||||
|
||||
<!ELEMENT site (#PCDATA)>
|
||||
<!ELEMENT title (#PCDATA)>
|
||||
<!ELEMENT summary (#PCDATA)>
|
||||
<!ELEMENT icon (#PCDATA)>
|
||||
|
||||
<!ELEMENT link (#PCDATA)>
|
||||
<!ATTLIST link
|
||||
rel (main|search|signIn|signOut|signUp|refillAccount|recoverPassword) #REQUIRED
|
||||
type CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT relationAliases (alias+)>
|
||||
<!ELEMENT alias EMPTY>
|
||||
<!ATTLIST alias
|
||||
alias CDATA #REQUIRED
|
||||
name CDATA #REQUIRED
|
||||
type CDATA ""
|
||||
>
|
||||
|
||||
<!ELEMENT advancedSearch (field+)>
|
||||
<!ATTLIST advancedSearch
|
||||
style (separateWords|quoted) #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT field (#PCDATA)>
|
||||
<!ATTLIST field
|
||||
name (author|titleOrSeries|tag|annotation) #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT feeds (condition+)>
|
||||
|
||||
<!ELEMENT condition (#PCDATA)>
|
||||
<!ATTLIST condition
|
||||
show (never|signedIn) #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT authentication EMPTY>
|
||||
<!ATTLIST authentication
|
||||
type (basic|litres) #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT urlRewritingRules (rule+)>
|
||||
|
||||
<!ELEMENT rule EMPTY>
|
||||
<!ATTLIST rule
|
||||
type (addUrlParameter) #REQUIRED
|
||||
apply (always|external|internal) "always"
|
||||
name CDATA #REQUIRED
|
||||
value CDATA #REQUIRED
|
||||
>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE catalog SYSTEM "catalog.dtd">
|
||||
<catalog type="opds">
|
||||
<catalog type="opds" hasStableIdentifiers="true">
|
||||
<site>feedbooks.com</site>
|
||||
<title>Feedbooks OPDS Catalog</title>
|
||||
<summary>Feedbooks: Food for the mind. A place to discover and publish e-books.</summary>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE catalog SYSTEM "catalog.dtd">
|
||||
<catalog type="opds">
|
||||
<catalog type="opds" hasStableIdentifiers="true">
|
||||
<site>litres.ru</site>
|
||||
<title>Каталог LitRes</title>
|
||||
<summary>Продажа электронных книг.</summary>
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.geometerplus.android.fbreader.network;
|
|||
|
||||
import org.geometerplus.zlibrary.core.resources.ZLResource;
|
||||
|
||||
import org.geometerplus.fbreader.network.NetworkLibraryItem;
|
||||
import org.geometerplus.fbreader.network.NetworkTree;
|
||||
|
||||
|
||||
|
@ -39,4 +40,9 @@ public class AddCustomCatalogItemTree extends NetworkTree {
|
|||
public String getSummary() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,16 @@
|
|||
|
||||
package org.geometerplus.android.fbreader.network;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import android.os.Message;
|
||||
import android.os.Handler;
|
||||
|
||||
import org.geometerplus.fbreader.network.INetworkLink;
|
||||
import org.geometerplus.fbreader.network.NetworkLibraryItem;
|
||||
|
||||
|
||||
|
@ -34,15 +38,31 @@ abstract class ItemsLoadingHandler extends Handler {
|
|||
private static final int WHAT_FINISHED = 1;
|
||||
|
||||
private final LinkedList<NetworkLibraryItem> myItems = new LinkedList<NetworkLibraryItem>();
|
||||
private final HashMap<INetworkLink, LinkedList<NetworkLibraryItem>> myUncommitedItems = new HashMap<INetworkLink, LinkedList<NetworkLibraryItem>>();
|
||||
private final Object myItemsMonitor = new Object();
|
||||
|
||||
private volatile boolean myFinishProcessed;
|
||||
private final Object myFinishMonitor = new Object();
|
||||
|
||||
|
||||
public final void addItem(NetworkLibraryItem item) {
|
||||
public final void addItem(INetworkLink link, NetworkLibraryItem item) {
|
||||
synchronized (myItemsMonitor) {
|
||||
myItems.add(item);
|
||||
LinkedList<NetworkLibraryItem> uncommited = myUncommitedItems.get(link);
|
||||
if (uncommited == null) {
|
||||
uncommited = new LinkedList<NetworkLibraryItem>();
|
||||
myUncommitedItems.put(link, uncommited);
|
||||
}
|
||||
uncommited.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public final void commitItems(INetworkLink link) {
|
||||
synchronized (myItemsMonitor) {
|
||||
LinkedList<NetworkLibraryItem> uncommited = myUncommitedItems.get(link);
|
||||
if (uncommited != null) {
|
||||
uncommited.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,8 +98,14 @@ abstract class ItemsLoadingHandler extends Handler {
|
|||
}
|
||||
|
||||
private final void doProcessFinish(String errorMessage, boolean interrupted) {
|
||||
HashSet<NetworkLibraryItem> uncommitedItems = new HashSet<NetworkLibraryItem>();
|
||||
synchronized (myUncommitedItems) {
|
||||
for (LinkedList<NetworkLibraryItem> items: myUncommitedItems.values()) {
|
||||
uncommitedItems.addAll(items);
|
||||
}
|
||||
}
|
||||
synchronized (myFinishMonitor) {
|
||||
onFinish(errorMessage, interrupted);
|
||||
onFinish(errorMessage, interrupted, uncommitedItems);
|
||||
myFinishProcessed = true;
|
||||
myFinishMonitor.notifyAll(); // wake up process, that waits for finish condition (see ensureFinish() method)
|
||||
}
|
||||
|
@ -100,7 +126,7 @@ abstract class ItemsLoadingHandler extends Handler {
|
|||
// callbacks
|
||||
public abstract void onUpdateItems(List<NetworkLibraryItem> items);
|
||||
public abstract void afterUpdateItems();
|
||||
public abstract void onFinish(String errorMessage, boolean interrupted);
|
||||
public abstract void onFinish(String errorMessage, boolean interrupted, Set<NetworkLibraryItem> uncommitedItems);
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.geometerplus.android.fbreader.network;
|
|||
import android.os.Message;
|
||||
import android.os.Handler;
|
||||
|
||||
import org.geometerplus.fbreader.network.INetworkLink;
|
||||
import org.geometerplus.fbreader.network.NetworkOperationData;
|
||||
import org.geometerplus.fbreader.network.NetworkLibraryItem;
|
||||
|
||||
|
@ -98,8 +99,8 @@ abstract class ItemsLoadingRunnable implements Runnable {
|
|||
err = doLoading(new NetworkOperationData.OnNewItemListener() {
|
||||
private long myUpdateTime;
|
||||
private int myItemsNumber;
|
||||
public void onNewItem(NetworkLibraryItem item) {
|
||||
myHandler.addItem(item);
|
||||
public void onNewItem(INetworkLink link, NetworkLibraryItem item) {
|
||||
myHandler.addItem(link, item);
|
||||
++myItemsNumber;
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now > myUpdateTime) {
|
||||
|
@ -110,6 +111,9 @@ abstract class ItemsLoadingRunnable implements Runnable {
|
|||
public boolean confirmInterrupt() {
|
||||
return confirmInterruptLoading() || myItemsNumber >= ItemsLimit;
|
||||
}
|
||||
public void commitItems(INetworkLink link) {
|
||||
myHandler.commitItems(link);
|
||||
}
|
||||
});
|
||||
myHandler.sendUpdateItems();
|
||||
myHandler.ensureItemsProcessed();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.geometerplus.android.fbreader.network;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.os.Message;
|
||||
|
@ -274,6 +275,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
|
|||
myKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateItems(List<NetworkLibraryItem> items) {
|
||||
for (NetworkLibraryItem item: items) {
|
||||
myTree.ChildrenItems.add(item);
|
||||
|
@ -281,20 +283,26 @@ class NetworkCatalogActions extends NetworkTreeActions {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterUpdateItems() {
|
||||
if (NetworkView.Instance().isInitialized()) {
|
||||
NetworkView.Instance().fireModelChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void onFinish(String errorMessage, boolean interrupted) {
|
||||
@Override
|
||||
public void onFinish(String errorMessage, boolean interrupted,
|
||||
Set<NetworkLibraryItem> uncommitedItems) {
|
||||
if (interrupted &&
|
||||
(!myTree.Item.supportsResumeLoading() || errorMessage != null)) {
|
||||
myTree.ChildrenItems.clear();
|
||||
myTree.clear();
|
||||
} else {
|
||||
myTree.removeItems(uncommitedItems);
|
||||
myTree.updateLoadedTime();
|
||||
afterUpdateCatalog(errorMessage, myTree.ChildrenItems.size() == 0);
|
||||
if (!interrupted) {
|
||||
afterUpdateCatalog(errorMessage, myTree.ChildrenItems.size() == 0);
|
||||
}
|
||||
final NetworkLibrary library = NetworkLibrary.Instance();
|
||||
library.invalidateVisibility();
|
||||
library.synchronize();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.geometerplus.android.fbreader.network;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Activity;
|
||||
|
@ -62,6 +63,7 @@ public class NetworkSearchActivity extends Activity {
|
|||
myTree = tree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateItems(List<NetworkLibraryItem> items) {
|
||||
SearchResult result = myTree.getSearchResult();
|
||||
for (NetworkLibraryItem item: items) {
|
||||
|
@ -71,6 +73,7 @@ public class NetworkSearchActivity extends Activity {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterUpdateItems() {
|
||||
myTree.updateSubTrees();
|
||||
if (NetworkView.Instance().isInitialized()) {
|
||||
|
@ -78,7 +81,9 @@ public class NetworkSearchActivity extends Activity {
|
|||
}
|
||||
}
|
||||
|
||||
public void onFinish(String errorMessage, boolean interrupted) {
|
||||
@Override
|
||||
public void onFinish(String errorMessage, boolean interrupted,
|
||||
Set<NetworkLibraryItem> uncommitedItems) {
|
||||
if (interrupted) {
|
||||
myTree.setSearchResult(null);
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.geometerplus.zlibrary.core.resources.ZLResource;
|
|||
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
||||
|
||||
import org.geometerplus.fbreader.network.INetworkLink;
|
||||
import org.geometerplus.fbreader.network.NetworkLibraryItem;
|
||||
import org.geometerplus.fbreader.network.NetworkTree;
|
||||
import org.geometerplus.fbreader.network.tree.NetworkCatalogTree;
|
||||
import org.geometerplus.fbreader.network.authentication.NetworkAuthenticationManager;
|
||||
|
@ -61,4 +62,9 @@ class RefillAccountTree extends NetworkTree {
|
|||
protected ZLImage createCover() {
|
||||
return Cover;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,4 +99,9 @@ public class SearchItemTree extends NetworkTree {
|
|||
throw new RuntimeException("That's impossible!!!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -411,12 +411,15 @@ public class NetworkLibrary {
|
|||
LinkedList<NetworkOperationData> dataList = new LinkedList<NetworkOperationData>();
|
||||
|
||||
final NetworkOperationData.OnNewItemListener synchronizedListener = new NetworkOperationData.OnNewItemListener() {
|
||||
public synchronized void onNewItem(NetworkLibraryItem item) {
|
||||
listener.onNewItem(item);
|
||||
public synchronized void onNewItem(INetworkLink link, NetworkLibraryItem item) {
|
||||
listener.onNewItem(link, item);
|
||||
}
|
||||
public synchronized boolean confirmInterrupt() {
|
||||
return listener.confirmInterrupt();
|
||||
}
|
||||
public synchronized void commitItems(INetworkLink link) {
|
||||
listener.commitItems(link);
|
||||
}
|
||||
};
|
||||
|
||||
synchronized (myLinks) {
|
||||
|
|
|
@ -25,9 +25,12 @@ import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
|
|||
public class NetworkOperationData {
|
||||
|
||||
public interface OnNewItemListener {
|
||||
void onNewItem(NetworkLibraryItem item);
|
||||
void onNewItem(INetworkLink link, NetworkLibraryItem item);
|
||||
|
||||
// return true to confirm interrupt reading; return false to continue reading
|
||||
void commitItems(INetworkLink link);
|
||||
|
||||
// returns true to confirm interrupt reading; return false to continue reading.
|
||||
// once true has been returned, all next calls must return true.
|
||||
boolean confirmInterrupt();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
package org.geometerplus.fbreader.network;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import org.geometerplus.fbreader.tree.FBTree;
|
||||
|
||||
import org.geometerplus.zlibrary.core.image.ZLImage;
|
||||
|
@ -80,4 +83,33 @@ public abstract class NetworkTree extends FBTree {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public abstract NetworkLibraryItem getHoldedItem();
|
||||
|
||||
public void removeItems(Set<NetworkLibraryItem> items) {
|
||||
if (items.isEmpty() || subTrees().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final LinkedList<FBTree> treesList = new LinkedList<FBTree>();
|
||||
for (FBTree tree: subTrees()) {
|
||||
final NetworkLibraryItem treeItem = ((NetworkTree)tree).getHoldedItem();
|
||||
if (treeItem != null && items.contains(treeItem)) {
|
||||
treesList.add(tree);
|
||||
items.remove(treeItem);
|
||||
}
|
||||
}
|
||||
for (FBTree tree: treesList) {
|
||||
tree.removeSelf();
|
||||
}
|
||||
if (items.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
treesList.clear();
|
||||
treesList.addAll(subTrees());
|
||||
while (!treesList.isEmpty()) {
|
||||
final NetworkTree tree = (NetworkTree) treesList.remove(treesList.size() - 1);
|
||||
tree.removeItems(items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,9 @@ public class LitResBookshelfItem extends NetworkCatalogItem {
|
|||
mgr.collectPurchasedBooks(children);
|
||||
Collections.sort(children, new NetworkBookItemComparator());
|
||||
for (NetworkLibraryItem item: children) {
|
||||
listener.onNewItem(item);
|
||||
listener.onNewItem(Link, item);
|
||||
}
|
||||
listener.commitItems(Link);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader {
|
|||
private int myIndex;
|
||||
|
||||
private String myNextURL;
|
||||
private String mySkipUntilTitle;
|
||||
private String mySkipUntilId;
|
||||
|
||||
private int myItemsToLoad = -1;
|
||||
|
||||
|
@ -50,7 +50,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader {
|
|||
NetworkOPDSFeedReader(String baseURL, OPDSCatalogItem.State result) {
|
||||
myBaseURL = baseURL;
|
||||
myData = result;
|
||||
mySkipUntilTitle = myData.LastLoadedTitle;
|
||||
mySkipUntilId = myData.LastLoadedId;
|
||||
if (!(result.Link instanceof OPDSLink)) {
|
||||
throw new IllegalArgumentException("Parameter `result` has invalid `Link` field value: result.Link must be an instance of OPDSLink class.");
|
||||
}
|
||||
|
@ -91,14 +91,14 @@ class NetworkOPDSFeedReader implements OPDSFeedReader {
|
|||
}
|
||||
|
||||
public void processFeedEnd() {
|
||||
if (mySkipUntilTitle != null) {
|
||||
if (mySkipUntilId != null) {
|
||||
// Last loaded element was not found => resume error => DO NOT RESUME
|
||||
// TODO: notify user about error???
|
||||
// TODO: do reload???
|
||||
myNextURL = null;
|
||||
}
|
||||
myData.ResumeURI = myNextURL;
|
||||
myData.LastLoadedTitle = null;
|
||||
myData.LastLoadedId = null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,13 +142,13 @@ class NetworkOPDSFeedReader implements OPDSFeedReader {
|
|||
--myItemsToLoad;
|
||||
}
|
||||
|
||||
if (mySkipUntilTitle != null) {
|
||||
if (mySkipUntilTitle.equals(entry.Title)) {
|
||||
mySkipUntilTitle = null;
|
||||
if (mySkipUntilId != null) {
|
||||
if (mySkipUntilId.equals(entry.Id.Uri)) {
|
||||
mySkipUntilId = null;
|
||||
}
|
||||
return tryInterrupt();
|
||||
}
|
||||
myData.LastLoadedTitle = entry.Title;
|
||||
myData.LastLoadedId = entry.Id.Uri;
|
||||
|
||||
final OPDSLink opdsLink = (OPDSLink) myData.Link;
|
||||
if (opdsLink.getCondition(entry.Id.Uri) == OPDSLink.FeedCondition.NEVER) {
|
||||
|
@ -176,7 +176,7 @@ class NetworkOPDSFeedReader implements OPDSFeedReader {
|
|||
item = readCatalogItem(entry);
|
||||
}
|
||||
if (item != null) {
|
||||
myData.Listener.onNewItem(item);
|
||||
myData.Listener.onNewItem(myData.Link, item);
|
||||
}
|
||||
return tryInterrupt();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class OPDSCatalogItem extends NetworkCatalogItem {
|
|||
|
||||
static class State extends NetworkOperationData {
|
||||
|
||||
public String LastLoadedTitle;
|
||||
public String LastLoadedId;
|
||||
|
||||
public State(INetworkLink link, OnNewItemListener listener) {
|
||||
super(link, listener);
|
||||
|
|
|
@ -30,7 +30,7 @@ class OPDSCustomLink extends OPDSLink implements ICustomNetworkLink {
|
|||
private SaveLinkListener myListener;
|
||||
|
||||
OPDSCustomLink(int id, String siteName, String title, String summary, String icon, Map<String, String> links) {
|
||||
super(siteName, title, summary, icon, links);
|
||||
super(siteName, title, summary, icon, links, false);
|
||||
myId = id;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,12 @@ class OPDSLink extends AbstractNetworkLink {
|
|||
private LinkedList<URLRewritingRule> myUrlRewritingRules;
|
||||
private NetworkAuthenticationManager myAuthenticationManager;
|
||||
|
||||
OPDSLink(String siteName, String title, String summary, String icon, Map<String, String> links) {
|
||||
private final boolean myHasStableIdentifiers;
|
||||
|
||||
OPDSLink(String siteName, String title, String summary, String icon,
|
||||
Map<String, String> links, boolean hasStableIdentifiers) {
|
||||
super(siteName, title, summary, icon, links);
|
||||
myHasStableIdentifiers = hasStableIdentifiers;
|
||||
}
|
||||
|
||||
final void setRelationAliases(Map<RelationAlias, String> relationAliases) {
|
||||
|
@ -88,9 +92,23 @@ class OPDSLink extends AbstractNetworkLink {
|
|||
if (result.Listener.confirmInterrupt()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
new OPDSXMLReader(
|
||||
new NetworkOPDSFeedReader(URL, result)
|
||||
).read(inputStream);
|
||||
|
||||
if (result.Listener.confirmInterrupt()) {
|
||||
if (!myHasStableIdentifiers && result.LastLoadedId != null) {
|
||||
// If current catalog doesn't have stable identifiers
|
||||
// and catalog wasn't completely loaded (i.e. LastLoadedIdentifier is not null)
|
||||
// then reset state to load current page from the beginning
|
||||
result.LastLoadedId = null;
|
||||
} else {
|
||||
result.Listener.commitItems(OPDSLink.this);
|
||||
}
|
||||
} else {
|
||||
result.Listener.commitItems(OPDSLink.this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ public class OPDSLinkReader extends ZLXMLReaderAdapter {
|
|||
private String myTitle;
|
||||
private String mySummary;
|
||||
private String myIcon;
|
||||
private boolean myHasStableIdentifiers;
|
||||
|
||||
private final HashMap<String, String> myLinks = new HashMap<String, String>();
|
||||
|
||||
|
@ -60,7 +61,8 @@ public class OPDSLinkReader extends ZLXMLReaderAdapter {
|
|||
myTitle,
|
||||
mySummary,
|
||||
myIcon,
|
||||
myLinks
|
||||
myLinks,
|
||||
myHasStableIdentifiers
|
||||
);
|
||||
|
||||
/*if (!mySearchType.empty()) {
|
||||
|
@ -102,6 +104,7 @@ public class OPDSLinkReader extends ZLXMLReaderAdapter {
|
|||
|
||||
public INetworkLink readDocument(ZLFile file) {
|
||||
mySiteName = myTitle = mySummary = myIcon = /*mySearchType = */myAuthenticationType = mySSLCertificate = null;
|
||||
myHasStableIdentifiers = false;
|
||||
myLinks.clear();
|
||||
mySearchFields.clear();
|
||||
myUrlConditions.clear();
|
||||
|
@ -126,6 +129,7 @@ public class OPDSLinkReader extends ZLXMLReaderAdapter {
|
|||
}
|
||||
|
||||
|
||||
private static final String TAG_CATALOG = "catalog";
|
||||
private static final String TAG_SITE = "site";
|
||||
private static final String TAG_LINK = "link";
|
||||
private static final String TAG_TITLE = "title";
|
||||
|
@ -163,7 +167,10 @@ public class OPDSLinkReader extends ZLXMLReaderAdapter {
|
|||
@Override
|
||||
public boolean startElementHandler(String tag, ZLStringMap attributes) {
|
||||
tag = tag.intern();
|
||||
if (TAG_SITE == tag) {
|
||||
if (TAG_CATALOG == tag) {
|
||||
final String value = attributes.getValue("hasStableIdentifiers");
|
||||
myHasStableIdentifiers = value != null && value.equals("true");
|
||||
} else if (TAG_SITE == tag) {
|
||||
myState = READ_SITENAME;
|
||||
} else if (TAG_TITLE == tag) {
|
||||
myState = READ_TITLE;
|
||||
|
|
|
@ -118,4 +118,9 @@ public class NetworkAuthorTree extends NetworkTree {
|
|||
|
||||
myBooksNumber = books.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,4 +67,9 @@ public class NetworkBookTree extends NetworkTree {
|
|||
protected ZLImage createCover() {
|
||||
return createCover(Book);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return Book;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,4 +156,15 @@ public class NetworkCatalogTree extends NetworkTree {
|
|||
tree.removeSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return Item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeItems(Set<NetworkLibraryItem> items) {
|
||||
ChildrenItems.removeAll(items);
|
||||
super.removeItems(items);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,4 +85,17 @@ public class NetworkSeriesTree extends NetworkTree {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeItems(Set<NetworkLibraryItem> items) {
|
||||
super.removeItems(items);
|
||||
if (subTrees().isEmpty()) {
|
||||
removeSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.geometerplus.fbreader.network.tree;
|
||||
|
||||
import org.geometerplus.fbreader.network.NetworkLibraryItem;
|
||||
import org.geometerplus.fbreader.network.NetworkTree;
|
||||
|
||||
public final class RootTree extends NetworkTree {
|
||||
|
@ -26,4 +27,9 @@ public final class RootTree extends NetworkTree {
|
|||
public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkLibraryItem getHoldedItem() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue