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

support for multiple network catalogs has been implemented

This commit is contained in:
Nikolay Pultsin 2010-11-13 17:13:15 +00:00
parent da7b633eee
commit d1f6a9eab7
13 changed files with 73 additions and 33 deletions

View file

@ -64,6 +64,7 @@
<node name="refillAccount" value="Refill account"/> <node name="refillAccount" value="Refill account"/>
<node name="addCustomCatalog" value="Add catalog"/> <node name="addCustomCatalog" value="Add catalog"/>
<node name="refreshCatalogsList" value="Refresh catalogs"/> <node name="refreshCatalogsList" value="Refresh catalogs"/>
<node name="languages" value="Language filter"/>
</node> </node>
</node> </node>
<node name="networkBookView"> <node name="networkBookView">

View file

@ -70,6 +70,7 @@
<node name="lt" value="Lithuanian" /> <node name="lt" value="Lithuanian" />
<node name="nl" value="Dutch" /> <node name="nl" value="Dutch" />
<node name="no" value="Norwegian" /> <node name="no" value="Norwegian" />
<node name="pl" value="Polish" />
<node name="pt" value="Portuguese" /> <node name="pt" value="Portuguese" />
<node name="ru" value="Russian" /> <node name="ru" value="Russian" />
<node name="sv" value="Swedish" /> <node name="sv" value="Swedish" />
@ -78,6 +79,7 @@
<node name="vi" value="Vietnamese" /> <node name="vi" value="Vietnamese" />
<node name="zh" value="Chinese" /> <node name="zh" value="Chinese" />
<node name="other" value="Other" /> <node name="other" value="Other" />
<node name="multi" value="Multilanguage" />
</node> </node>
<node name="boolean3"> <node name="boolean3">
<node name="on" value="on" /> <node name="on" value="on" />

View file

@ -30,6 +30,7 @@ import android.widget.BaseAdapter;
import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.network.ZLNetworkException; import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.language.ZLLanguageUtil;
import org.geometerplus.zlibrary.ui.android.R; import org.geometerplus.zlibrary.ui.android.R;
@ -38,7 +39,6 @@ import org.geometerplus.android.util.AndroidUtil;
import org.geometerplus.fbreader.network.NetworkTree; import org.geometerplus.fbreader.network.NetworkTree;
import org.geometerplus.fbreader.network.NetworkLibrary; import org.geometerplus.fbreader.network.NetworkLibrary;
public class NetworkLibraryActivity extends NetworkBaseActivity { public class NetworkLibraryActivity extends NetworkBaseActivity {
private NetworkTree myTree; private NetworkTree myTree;
@ -206,6 +206,7 @@ public class NetworkLibraryActivity extends NetworkBaseActivity {
private static final int MENU_SEARCH = 1; private static final int MENU_SEARCH = 1;
private static final int MENU_REFRESH = 2; private static final int MENU_REFRESH = 2;
private static final int MENU_ADD_CATALOG = 3; private static final int MENU_ADD_CATALOG = 3;
private static final int MENU_LANGUAGES = 4;
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
@ -213,6 +214,7 @@ public class NetworkLibraryActivity extends NetworkBaseActivity {
addMenuItem(menu, MENU_SEARCH, "networkSearch", R.drawable.ic_menu_networksearch); addMenuItem(menu, MENU_SEARCH, "networkSearch", R.drawable.ic_menu_networksearch);
addMenuItem(menu, MENU_ADD_CATALOG, "addCustomCatalog", android.R.drawable.ic_menu_add); addMenuItem(menu, MENU_ADD_CATALOG, "addCustomCatalog", android.R.drawable.ic_menu_add);
addMenuItem(menu, MENU_REFRESH, "refreshCatalogsList", R.drawable.ic_menu_refresh); addMenuItem(menu, MENU_REFRESH, "refreshCatalogsList", R.drawable.ic_menu_refresh);
addMenuItem(menu, MENU_LANGUAGES, "languages", 0);
return true; return true;
} }
@ -235,6 +237,11 @@ public class NetworkLibraryActivity extends NetworkBaseActivity {
case MENU_REFRESH: case MENU_REFRESH:
refreshCatalogsList(); refreshCatalogsList();
return true; return true;
case MENU_LANGUAGES:
for (String langCode : NetworkLibrary.Instance().languages()) {
System.err.println("Language: " + ZLLanguageUtil.languageName(langCode));
}
return true;
default: default:
return true; return true;
} }

View file

@ -25,7 +25,7 @@ import java.util.TreeMap;
import android.content.Context; import android.content.Context;
import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.language.ZLLanguageList; import org.geometerplus.zlibrary.core.language.ZLLanguageUtil;
import org.geometerplus.zlibrary.text.hyphenation.ZLTextHyphenator; import org.geometerplus.zlibrary.text.hyphenation.ZLTextHyphenator;
@ -53,8 +53,8 @@ class LanguagePreference extends ZLStringListPreference {
super(context, rootResource, resourceKey); super(context, rootResource, resourceKey);
myBook = book; myBook = book;
final TreeMap<String,String> map = new TreeMap<String,String>(); final TreeMap<String,String> map = new TreeMap<String,String>();
for (String code : ZLLanguageList.languageCodes()) { for (String code : ZLLanguageUtil.languageCodes()) {
map.put(ZLLanguageList.languageName(code), code); map.put(ZLLanguageUtil.languageName(code), code);
} }
final int size = map.size(); final int size = map.size();
String[] codes = new String[size + 1]; String[] codes = new String[size + 1];
@ -65,15 +65,15 @@ class LanguagePreference extends ZLStringListPreference {
names[index] = entry.getKey(); names[index] = entry.getKey();
++index; ++index;
} }
codes[size] = "other"; codes[size] = ZLLanguageUtil.OTHER_LANGUAGE_CODE;
names[size] = ZLLanguageList.languageName(codes[size]); names[size] = ZLLanguageUtil.languageName(codes[size]);
setLists(codes, names); setLists(codes, names);
String language = myBook.getLanguage(); String language = myBook.getLanguage();
if (language == null) { if (language == null) {
language = "other"; language = ZLLanguageUtil.OTHER_LANGUAGE_CODE;
} }
if (!setInitialValue(language)) { if (!setInitialValue(language)) {
setInitialValue("other"); setInitialValue(ZLLanguageUtil.OTHER_LANGUAGE_CODE);
} }
} }

View file

@ -25,15 +25,13 @@ import java.util.TreeMap;
import org.geometerplus.zlibrary.core.util.ZLMiscUtil; import org.geometerplus.zlibrary.core.util.ZLMiscUtil;
public abstract class AbstractNetworkLink implements INetworkLink { public abstract class AbstractNetworkLink implements INetworkLink {
protected String mySiteName; protected String mySiteName;
protected String myTitle; protected String myTitle;
protected String mySummary; protected String mySummary;
protected String myIcon; protected String myIcon;
protected TreeMap<String, String> myLinks; protected final String myLanguage;
protected final TreeMap<String, String> myLinks;
/** /**
* Creates new NetworkLink instance. * Creates new NetworkLink instance.
@ -42,13 +40,15 @@ public abstract class AbstractNetworkLink implements INetworkLink {
* @param title title of the corresponding library item. Must be not <code>null</code>. * @param title title of the corresponding library item. Must be not <code>null</code>.
* @param summary description of the corresponding library item. Can be <code>null</code>. * @param summary description of the corresponding library item. Can be <code>null</code>.
* @param icon string contains link's icon data/url. Can be <code>null</code>. * @param icon string contains link's icon data/url. Can be <code>null</code>.
* @param language language of the catalog. If <code>null</code> we assume this catalog is multilanguage.
* @param links map contains URLs with their identifiers; must always contain one URL with <code>URL_MAIN</code> identifier * @param links map contains URLs with their identifiers; must always contain one URL with <code>URL_MAIN</code> identifier
*/ */
public AbstractNetworkLink(String siteName, String title, String summary, String icon, Map<String, String> links) { public AbstractNetworkLink(String siteName, String title, String summary, String icon, String language, Map<String, String> links) {
mySiteName = siteName; mySiteName = siteName;
myTitle = title; myTitle = title;
mySummary = summary; mySummary = summary;
myIcon = icon; myIcon = icon;
myLanguage = language != null ? language : "multi";
myLinks = new TreeMap<String, String>(links); myLinks = new TreeMap<String, String>(links);
} }
@ -68,6 +68,10 @@ public abstract class AbstractNetworkLink implements INetworkLink {
return myIcon; return myIcon;
} }
public String getLanguage() {
return myLanguage;
}
public String getLink(String urlKey) { public String getLink(String urlKey) {
return myLinks.get(urlKey); return myLinks.get(urlKey);
} }

View file

@ -41,6 +41,7 @@ public interface INetworkLink {
String getSummary(); String getSummary();
String getIcon(); String getIcon();
String getLink(String urlKey); String getLink(String urlKey);
String getLanguage();
Set<String> getLinkKeys(); Set<String> getLinkKeys();

View file

@ -26,6 +26,7 @@ import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.network.ZLNetworkManager; import org.geometerplus.zlibrary.core.network.ZLNetworkManager;
import org.geometerplus.zlibrary.core.network.ZLNetworkException; import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.network.ZLNetworkRequest; import org.geometerplus.zlibrary.core.network.ZLNetworkRequest;
import org.geometerplus.zlibrary.core.language.ZLLanguageUtil;
import org.geometerplus.fbreader.tree.FBTree; import org.geometerplus.fbreader.tree.FBTree;
import org.geometerplus.fbreader.network.tree.*; import org.geometerplus.fbreader.network.tree.*;
@ -43,14 +44,11 @@ public class NetworkLibrary {
} }
private static class CompositeList extends AbstractSequentialList<INetworkLink> { private static class CompositeList extends AbstractSequentialList<INetworkLink> {
private final ArrayList<ArrayList<? extends INetworkLink>> myLists; private final ArrayList<ArrayList<? extends INetworkLink>> myLists;
private Comparator<INetworkLink> myComparator; private final Comparator<INetworkLink> myComparator = new LinksComparator();
public CompositeList(ArrayList<ArrayList<? extends INetworkLink>> lists, public CompositeList(ArrayList<ArrayList<? extends INetworkLink>> lists) {
Comparator<INetworkLink> comparator) {
myLists = lists; myLists = lists;
myComparator = comparator;
} }
private class Iterator implements ListIterator<INetworkLink> { private class Iterator implements ListIterator<INetworkLink> {
@ -195,7 +193,22 @@ public class NetworkLibrary {
return title; return title;
} }
private static int languageOrder(String language) {
if (language == ZLLanguageUtil.MULTI_LANGUAGE_CODE) {
return 1;
}
if (language.equals(Locale.getDefault().getLanguage())) {
return 0;
}
return 2;
}
public int compare(INetworkLink link1, INetworkLink link2) { public int compare(INetworkLink link1, INetworkLink link2) {
final int languageOrder1 = languageOrder(link1.getLanguage());
final int languageOrder2 = languageOrder(link2.getLanguage());
if (languageOrder1 != languageOrder2) {
return languageOrder1 - languageOrder2;
}
final String title1 = filterLinkTitle(link1.getTitle()); final String title1 = filterLinkTitle(link1.getTitle());
final String title2 = filterLinkTitle(link2.getTitle()); final String title2 = filterLinkTitle(link2.getTitle());
return title1.compareToIgnoreCase(title2); return title1.compareToIgnoreCase(title2);
@ -224,7 +237,7 @@ public class NetworkLibrary {
ArrayList<ArrayList<? extends INetworkLink>> linksList = new ArrayList<ArrayList<? extends INetworkLink>>(); ArrayList<ArrayList<? extends INetworkLink>> linksList = new ArrayList<ArrayList<? extends INetworkLink>>();
linksList.add(myLoadedLinks); linksList.add(myLoadedLinks);
linksList.add(myCustomLinks); linksList.add(myCustomLinks);
myLinks = new CompositeList(linksList, new LinksComparator()); myLinks = new CompositeList(linksList);
} }
private boolean myIsAlreadyInitialized; private boolean myIsAlreadyInitialized;
@ -477,9 +490,7 @@ public class NetworkLibrary {
public void synchronize() { public void synchronize() {
if (myUpdateChildren || myInvalidateChildren) { if (myUpdateChildren || myInvalidateChildren) {
if (myInvalidateChildren) { if (myInvalidateChildren) {
final LinksComparator cmp = new LinksComparator(); Collections.sort(myCustomLinks, new LinksComparator());
//Collections.sort(myLoadedLinks, cmp); // this collection is always sorted
Collections.sort(myCustomLinks, cmp);
} }
myUpdateChildren = false; myUpdateChildren = false;
myInvalidateChildren = false; myInvalidateChildren = false;
@ -553,7 +564,8 @@ public class NetworkLibrary {
synchronized (myLinks) { synchronized (myLinks) {
final int index = Collections.binarySearch(list, link, comparator); final int index = Collections.binarySearch(list, link, comparator);
if (index >= 0) { if (index >= 0) {
throw new RuntimeException("Unable to add link with duplicated title to the library"); return;
//throw new RuntimeException("Unable to add link with duplicated title to the library");
} }
final int insertAt = -index - 1; final int insertAt = -index - 1;
list.add(insertAt, link); list.add(insertAt, link);
@ -599,4 +611,12 @@ public class NetworkLibrary {
} }
return false; return false;
} }
public List<String> languages() {
final TreeSet<String> languageSet = new TreeSet<String>();
for (INetworkLink link : myLoadedLinks) {
languageSet.add(link.getLanguage());
}
return new ArrayList(languageSet);
}
} }

View file

@ -42,7 +42,7 @@ class OPDSCustomLink extends OPDSNetworkLink implements ICustomNetworkLink {
private boolean myHasChanges; private boolean myHasChanges;
OPDSCustomLink(int id, String siteName, String title, String summary, String icon, Map<String, String> links) { OPDSCustomLink(int id, String siteName, String title, String summary, String icon, Map<String, String> links) {
super(siteName, title, summary, icon, links, false); super(siteName, title, summary, icon, null, links, false);
myId = id; myId = id;
} }

View file

@ -39,7 +39,7 @@ import org.geometerplus.fbreader.network.atom.ATOMUpdated;
public class OPDSLinkReader { public class OPDSLinkReader {
static final String CATALOGS_URL = "http://data.fbreader.org/catalogs/generic-1.0.xml"; static final String CATALOGS_URL = "http://data.fbreader.org/catalogs/generic-1.1.xml";
public static ICustomNetworkLink createCustomLink(int id, String siteName, String title, String summary, String icon, Map<String, String> links) { public static ICustomNetworkLink createCustomLink(int id, String siteName, String title, String summary, String icon, Map<String, String> links) {
if (siteName == null || title == null || links.get(INetworkLink.URL_MAIN) == null) { if (siteName == null || title == null || links.get(INetworkLink.URL_MAIN) == null) {

View file

@ -93,6 +93,7 @@ class OPDSLinkXMLReader extends OPDSXMLReader {
final String siteName = id.substring(ENTRY_ID_PREFIX.length()); final String siteName = id.substring(ENTRY_ID_PREFIX.length());
final String title = entry.Title; final String title = entry.Title;
final String summary = entry.Content; final String summary = entry.Content;
final String language = entry.DCLanguage;
String icon = null; String icon = null;
final HashMap<String, String> links = new HashMap<String, String>(); final HashMap<String, String> links = new HashMap<String, String>();
@ -151,14 +152,14 @@ class OPDSLinkXMLReader extends OPDSXMLReader {
sslCertificate = null; sslCertificate = null;
} }
INetworkLink result = link(siteName, title, summary, icon, links, urlConditions, sslCertificate); INetworkLink result = link(siteName, title, summary, icon, language, links, urlConditions, sslCertificate);
if (result != null) { if (result != null) {
myListener.onNewLink(result); myListener.onNewLink(result);
} }
return false; return false;
} }
private INetworkLink link(String siteName, String title, String summary, String icon, private INetworkLink link(String siteName, String title, String summary, String icon, String language,
Map<String, String> links, HashMap<String, Integer> urlConditions, String sslCertificate) { Map<String, String> links, HashMap<String, Integer> urlConditions, String sslCertificate) {
if (siteName == null || title == null || links.get(INetworkLink.URL_MAIN) == null) { if (siteName == null || title == null || links.get(INetworkLink.URL_MAIN) == null) {
return null; return null;
@ -169,6 +170,7 @@ class OPDSLinkXMLReader extends OPDSXMLReader {
title, title,
summary, summary,
icon, icon,
language,
links, links,
myHasStableIdentifiers myHasStableIdentifiers
); );

View file

@ -49,9 +49,9 @@ class OPDSNetworkLink extends AbstractNetworkLink {
private final boolean myHasStableIdentifiers; private final boolean myHasStableIdentifiers;
OPDSNetworkLink(String siteName, String title, String summary, String icon, OPDSNetworkLink(String siteName, String title, String summary, String icon, String language,
Map<String, String> links, boolean hasStableIdentifiers) { Map<String, String> links, boolean hasStableIdentifiers) {
super(siteName, title, summary, icon, links); super(siteName, title, summary, icon, language, links);
myHasStableIdentifiers = hasStableIdentifiers; myHasStableIdentifiers = hasStableIdentifiers;
} }

View file

@ -64,7 +64,7 @@ public class ZLLanguageDetector {
}; };
public ZLLanguageDetector() { public ZLLanguageDetector() {
for (ZLFile file : ZLLanguageList.patternsFile().children()) { for (ZLFile file : ZLLanguageUtil.patternsFile().children()) {
final String name = file.getName(true); final String name = file.getName(true);
final int index = name.indexOf('_'); final int index = name.indexOf('_');
if (index != -1) { if (index != -1) {

View file

@ -24,10 +24,13 @@ import java.util.*;
import org.geometerplus.zlibrary.core.filesystem.*; import org.geometerplus.zlibrary.core.filesystem.*;
import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.resources.ZLResource;
public abstract class ZLLanguageList { public abstract class ZLLanguageUtil {
public static final String OTHER_LANGUAGE_CODE = "other";
public static final String MULTI_LANGUAGE_CODE = "multi";
private static ArrayList<String> ourLanguageCodes = new ArrayList<String>(); private static ArrayList<String> ourLanguageCodes = new ArrayList<String>();
private ZLLanguageList() { private ZLLanguageUtil() {
} }
public static List<String> languageCodes() { public static List<String> languageCodes() {
@ -54,7 +57,7 @@ public abstract class ZLLanguageList {
return ZLResource.resource("language").getResource(code).getValue(); return ZLResource.resource("language").getResource(code).getValue();
} }
public static ZLFile patternsFile() { public static ZLFile patternsFile() {
return ZLResourceFile.createResourceFile("languagePatterns"); return ZLResourceFile.createResourceFile("languagePatterns");
} }
} }