1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 10:49:24 +02:00

Title => TitledEntity

This commit is contained in:
Nikolay Pultsin 2013-03-09 19:11:57 +04:00
parent b54e36bd53
commit 8d0b00bf7a
16 changed files with 159 additions and 111 deletions

View file

@ -241,7 +241,7 @@ public class BookInfoActivity extends Activity {
setupInfoPair(R.id.book_authors, "authors", buffer, authors.size()); setupInfoPair(R.id.book_authors, "authors", buffer, authors.size());
final SeriesInfo series = book.getSeriesInfo(); final SeriesInfo series = book.getSeriesInfo();
setupInfoPair(R.id.book_series, "series", series == null ? null : series.Title); setupInfoPair(R.id.book_series, "series", series == null ? null : series.Series.getTitle());
String seriesIndexString = null; String seriesIndexString = null;
if (series != null && series.Index != null) { if (series != null && series.Index != null) {
seriesIndexString = series.Index.toString(); seriesIndexString = series.Index.toString();

View file

@ -492,10 +492,10 @@ final class SQLiteBooksDatabase extends BooksDatabase {
} else { } else {
long seriesId; long seriesId;
try { try {
myGetSeriesIdStatement.bindString(1, seriesInfo.Title); myGetSeriesIdStatement.bindString(1, seriesInfo.Series.getTitle());
seriesId = myGetSeriesIdStatement.simpleQueryForLong(); seriesId = myGetSeriesIdStatement.simpleQueryForLong();
} catch (SQLException e) { } catch (SQLException e) {
myInsertSeriesStatement.bindString(1, seriesInfo.Title); myInsertSeriesStatement.bindString(1, seriesInfo.Series.getTitle());
seriesId = myInsertSeriesStatement.executeInsert(); seriesId = myInsertSeriesStatement.executeInsert();
} }
myInsertBookSeriesStatement.bindLong(1, bookId); myInsertBookSeriesStatement.bindLong(1, bookId);

View file

@ -37,9 +37,9 @@ import org.geometerplus.zlibrary.text.view.ZLTextPosition;
import org.geometerplus.fbreader.Paths; import org.geometerplus.fbreader.Paths;
import org.geometerplus.fbreader.bookmodel.BookReadingException; import org.geometerplus.fbreader.bookmodel.BookReadingException;
import org.geometerplus.fbreader.formats.*; import org.geometerplus.fbreader.formats.*;
import org.geometerplus.fbreader.sort.Title; import org.geometerplus.fbreader.sort.TitledEntity;
public class Book { public class Book extends TitledEntity {
public static final String FAVORITE_LABEL = "favorite"; public static final String FAVORITE_LABEL = "favorite";
public final ZLFile File; public final ZLFile File;
@ -47,7 +47,7 @@ public class Book {
private volatile long myId; private volatile long myId;
private volatile String myEncoding; private volatile String myEncoding;
private volatile Title myInfo; private volatile String myLanguage;
private volatile List<Author> myAuthors; private volatile List<Author> myAuthors;
private volatile List<Tag> myTags; private volatile List<Tag> myTags;
private volatile SeriesInfo mySeriesInfo; private volatile SeriesInfo mySeriesInfo;
@ -58,14 +58,16 @@ public class Book {
private WeakReference<ZLImage> myCover; private WeakReference<ZLImage> myCover;
Book(long id, ZLFile file, String title, String encoding, String language) { Book(long id, ZLFile file, String title, String encoding, String language) {
super(title);
myId = id; myId = id;
File = file; File = file;
myInfo = new Title(title, language); myLanguage = language;
myEncoding = encoding; myEncoding = encoding;
myIsSaved = true; myIsSaved = true;
} }
Book(ZLFile file) throws BookReadingException { Book(ZLFile file) throws BookReadingException {
super(null);
myId = -1; myId = -1;
final FormatPlugin plugin = getPlugin(file); final FormatPlugin plugin = getPlugin(file);
File = plugin.realBookFile(file); File = plugin.realBookFile(file);
@ -77,7 +79,8 @@ public class Book {
if (myId != book.myId) { if (myId != book.myId) {
return; return;
} }
myInfo = book.myInfo; setTitle(book.getTitle());
myLanguage = book.myLanguage;
myEncoding = book.myEncoding; myEncoding = book.myEncoding;
myAuthors = book.myAuthors != null ? new ArrayList<Author>(book.myAuthors) : null; myAuthors = book.myAuthors != null ? new ArrayList<Author>(book.myAuthors) : null;
myTags = book.myTags != null ? new ArrayList<Tag>(book.myTags) : null; myTags = book.myTags != null ? new ArrayList<Tag>(book.myTags) : null;
@ -109,8 +112,9 @@ public class Book {
} }
private void readMetaInfo(FormatPlugin plugin) throws BookReadingException { private void readMetaInfo(FormatPlugin plugin) throws BookReadingException {
setTitle(null);
myEncoding = null; myEncoding = null;
myInfo = new Title (null, null); myLanguage = null;
myAuthors = null; myAuthors = null;
myTags = null; myTags = null;
mySeriesInfo = null; mySeriesInfo = null;
@ -119,7 +123,7 @@ public class Book {
plugin.readMetaInfo(this); plugin.readMetaInfo(this);
if (myInfo.getTitle() == null || myInfo.getTitle().length() == 0) { if (getTitle() == null || getTitle().length() == 0) {
final String fileName = File.getShortName(); final String fileName = File.getShortName();
final int index = fileName.lastIndexOf('.'); final int index = fileName.lastIndexOf('.');
setTitle(index > 0 ? fileName.substring(0, index) : fileName); setTitle(index > 0 ? fileName.substring(0, index) : fileName);
@ -204,13 +208,9 @@ public class Book {
return myId; return myId;
} }
public String getTitle() {
return myInfo.getTitle();
}
public void setTitle(String title) { public void setTitle(String title) {
if (!MiscUtil.equals(myInfo.getTitle(), title)) { if (!MiscUtil.equals(getTitle(), title)) {
myInfo.setTitle(title); super.setTitle(title);
myIsSaved = false; myIsSaved = false;
} }
} }
@ -236,23 +236,20 @@ public class Book {
} else if (name == null) { } else if (name == null) {
mySeriesInfo = null; mySeriesInfo = null;
myIsSaved = false; myIsSaved = false;
} else if (!name.equals(mySeriesInfo.Title) || mySeriesInfo.Index != index) { } else if (!name.equals(mySeriesInfo.Series.getTitle()) || mySeriesInfo.Index != index) {
mySeriesInfo = new SeriesInfo(name, index); mySeriesInfo = new SeriesInfo(name, index);
myIsSaved = false; myIsSaved = false;
} }
} }
public Title getInfo() {
return myInfo;
}
public String getLanguage() { public String getLanguage() {
return myInfo.getLanguage(); return myLanguage;
} }
public void setLanguage(String language) { public void setLanguage(String language) {
if (!MiscUtil.equals(myInfo.getLanguage(), language)) { if (!MiscUtil.equals(myLanguage, language)) {
myInfo.setLanguage(language); myLanguage = language;
resetSortKey();
myIsSaved = false; myIsSaved = false;
} }
} }
@ -316,10 +313,10 @@ public class Book {
} }
public boolean matches(String pattern) { public boolean matches(String pattern) {
if (myInfo.getTitle() != null && MiscUtil.matchesIgnoreCase(myInfo.getTitle(), pattern)) { if (getTitle() != null && MiscUtil.matchesIgnoreCase(getTitle(), pattern)) {
return true; return true;
} }
if (mySeriesInfo != null && MiscUtil.matchesIgnoreCase(mySeriesInfo.Title, pattern)) { if (mySeriesInfo != null && MiscUtil.matchesIgnoreCase(mySeriesInfo.Series.getTitle(), pattern)) {
return true; return true;
} }
if (myAuthors != null) { if (myAuthors != null) {
@ -351,9 +348,9 @@ public class Book {
public void run() { public void run() {
if (myId >= 0) { if (myId >= 0) {
final FileInfoSet fileInfos = new FileInfoSet(database, File); final FileInfoSet fileInfos = new FileInfoSet(database, File);
database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myInfo.getLanguage(), myInfo.getTitle()); database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myLanguage, getTitle());
} else { } else {
myId = database.insertBookInfo(File, myEncoding, myInfo.getLanguage(), myInfo.getTitle()); myId = database.insertBookInfo(File, myEncoding, myLanguage, getTitle());
if (myId != -1 && myVisitedHyperlinks != null) { if (myId != -1 && myVisitedHyperlinks != null) {
for (String linkId : myVisitedHyperlinks) { for (String linkId : myVisitedHyperlinks) {
database.addVisitedHyperlink(myId, linkId); database.addVisitedHyperlink(myId, linkId);

View file

@ -228,7 +228,7 @@ public class BookCollection extends AbstractBookCollection {
final LinkedList<Book> filtered = new LinkedList<Book>(); final LinkedList<Book> filtered = new LinkedList<Book>();
for (Book b : books()) { for (Book b : books()) {
final SeriesInfo info = b.getSeriesInfo(); final SeriesInfo info = b.getSeriesInfo();
if (info != null && series.equals(info.Title)) { if (info != null && series.equals(info.Series.getTitle())) {
filtered.add(b); filtered.add(b);
} }
} }
@ -241,7 +241,7 @@ public class BookCollection extends AbstractBookCollection {
for (Book b : books()) { for (Book b : books()) {
final List<Author> bookAuthors = b.authors(); final List<Author> bookAuthors = b.authors();
final SeriesInfo info = b.getSeriesInfo(); final SeriesInfo info = b.getSeriesInfo();
if (info != null && series.equals(info.Title) if (info != null && series.equals(info.Series.getTitle())
&& (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) { && (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) {
filtered.add(b); filtered.add(b);
} }
@ -358,7 +358,7 @@ public class BookCollection extends AbstractBookCollection {
for (Book book : myBooksByFile.values()) { for (Book book : myBooksByFile.values()) {
final SeriesInfo info = book.getSeriesInfo(); final SeriesInfo info = book.getSeriesInfo();
if (info != null) { if (info != null) {
series.add(info.Title); series.add(info.Series.getTitle());
} }
} }
} }
@ -402,7 +402,7 @@ public class BookCollection extends AbstractBookCollection {
synchronized (myBooksByFile) { synchronized (myBooksByFile) {
for (Book b : myBooksByFile.values()) { for (Book b : myBooksByFile.values()) {
final SeriesInfo info = b.getSeriesInfo(); final SeriesInfo info = b.getSeriesInfo();
if (info != null && series.equals(info.Title)) { if (info != null && series.equals(info.Series.getTitle())) {
titles.add(b.getTitle()); titles.add(b.getTitle());
if (--limit == 0) { if (--limit == 0) {
break; break;
@ -423,7 +423,7 @@ public class BookCollection extends AbstractBookCollection {
for (Book b : myBooksByFile.values()) { for (Book b : myBooksByFile.values()) {
final List<Author> bookAuthors = b.authors(); final List<Author> bookAuthors = b.authors();
final SeriesInfo info = b.getSeriesInfo(); final SeriesInfo info = b.getSeriesInfo();
if (info != null && series.equals(info.Title) if (info != null && series.equals(info.Series.getTitle())
&& (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) { && (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) {
titles.add(b.getTitle()); titles.add(b.getTitle());
if (--limit == 0) { if (--limit == 0) {

View file

@ -17,13 +17,35 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
package org.geometerplus.fbreader.sort; package org.geometerplus.fbreader.book;
import java.util.*; import org.geometerplus.zlibrary.core.util.MiscUtil;
import org.geometerplus.fbreader.sort.TitledEntity;
public class Series extends TitledEntity {
public Series(String title) {
super(title);
}
public String getLanguage() {
// TODO: return real language
return "en";
}
public class TitleComparator implements Comparator<Title> {
@Override @Override
public int compare(Title title0, Title title1) { public boolean equals(Object o) {
return title0.getSortKey().compareTo(title1.getSortKey()); if (this == o) {
return true;
}
if (!(o instanceof Series)) {
return false;
}
return MiscUtil.equals(getTitle(), ((Series)o).getTitle());
}
@Override
public int hashCode() {
return MiscUtil.hashCode(getTitle());
} }
} }

View file

@ -37,11 +37,11 @@ public final class SeriesInfo {
} }
} }
public final String Title; public final Series Series;
public final BigDecimal Index; public final BigDecimal Index;
SeriesInfo(String title, BigDecimal index) { SeriesInfo(String title, BigDecimal index) {
Title = title; Series = new Series(title);
Index = index; Index = index;
} }
} }

View file

@ -24,7 +24,7 @@ public abstract class TitleUtil {
if (book == null) { if (book == null) {
return null; return null;
} }
return firstLetter(book.getInfo().getSortKey()); return firstLetter(book.getSortKey());
} }
public static String firstLetter(String title) { public static String firstLetter(String title) {

View file

@ -63,7 +63,7 @@ class XMLSerializer extends AbstractSerializer {
final SeriesInfo seriesInfo = book.getSeriesInfo(); final SeriesInfo seriesInfo = book.getSeriesInfo();
if (seriesInfo != null) { if (seriesInfo != null) {
appendTagWithContent(buffer, "calibre:series", seriesInfo.Title); appendTagWithContent(buffer, "calibre:series", seriesInfo.Series.getTitle());
if (seriesInfo.Index != null) { if (seriesInfo.Index != null) {
appendTagWithContent(buffer, "calibre:series_index", seriesInfo.Index); appendTagWithContent(buffer, "calibre:series_index", seriesInfo.Index);
} }

View file

@ -107,7 +107,7 @@ public class AuthorTree extends LibraryTree {
} }
} }
private SeriesTree getSeriesSubTree(String series) { private SeriesTree getSeriesSubTree(Series series) {
final SeriesTree temp = new SeriesTree(Collection, series, Author); final SeriesTree temp = new SeriesTree(Collection, series, Author);
int position = Collections.binarySearch(subTrees(), temp); int position = Collections.binarySearch(subTrees(), temp);
if (position >= 0) { if (position >= 0) {
@ -120,7 +120,7 @@ public class AuthorTree extends LibraryTree {
private boolean createBookSubTree(Book book) { private boolean createBookSubTree(Book book) {
final SeriesInfo seriesInfo = book.getSeriesInfo(); final SeriesInfo seriesInfo = book.getSeriesInfo();
if (seriesInfo != null) { if (seriesInfo != null) {
return getSeriesSubTree(seriesInfo.Title).createBookInSeriesSubTree(book); return getSeriesSubTree(seriesInfo.Series).createBookInSeriesSubTree(book);
} }
final BookTree temp = new BookTree(Collection, book); final BookTree temp = new BookTree(Collection, book);

View file

@ -22,10 +22,10 @@ package org.geometerplus.fbreader.library;
import org.geometerplus.zlibrary.core.image.ZLImage; import org.geometerplus.zlibrary.core.image.ZLImage;
import org.geometerplus.fbreader.book.*; import org.geometerplus.fbreader.book.*;
import org.geometerplus.fbreader.sort.Title; import org.geometerplus.fbreader.sort.TitledEntity;
import org.geometerplus.fbreader.tree.FBTree; import org.geometerplus.fbreader.tree.FBTree;
public class BookTree extends LibraryTree { public class BookTree extends TitledEntityTree {
public final Book Book; public final Book Book;
BookTree(IBookCollection collection, Book book) { BookTree(IBookCollection collection, Book book) {
@ -97,8 +97,7 @@ public class BookTree extends LibraryTree {
} }
@Override @Override
public Title getTitle() { public TitledEntity getTitledEntity() {
// TODO Auto-generated method stub return Book;
return Book.getInfo();
} }
} }

View file

@ -24,8 +24,6 @@ import java.util.*;
import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.fbreader.book.*; import org.geometerplus.fbreader.book.*;
import org.geometerplus.fbreader.sort.Title;
import org.geometerplus.fbreader.sort.TitleComparator;
import org.geometerplus.fbreader.tree.FBTree; import org.geometerplus.fbreader.tree.FBTree;
public abstract class LibraryTree extends FBTree { public abstract class LibraryTree extends FBTree {
@ -35,8 +33,6 @@ public abstract class LibraryTree extends FBTree {
public final IBookCollection Collection; public final IBookCollection Collection;
private static final TitleComparator COMPARATOR = new TitleComparator();
static final String ROOT_FOUND = "found"; static final String ROOT_FOUND = "found";
static final String ROOT_FAVORITES = "favorites"; static final String ROOT_FAVORITES = "favorites";
static final String ROOT_RECENT = "recent"; static final String ROOT_RECENT = "recent";
@ -134,20 +130,10 @@ public abstract class LibraryTree extends FBTree {
@Override @Override
public int compareTo(FBTree tree) { public int compareTo(FBTree tree) {
final int cmp; final int cmp = super.compareTo(tree);
if (tree instanceof LibraryTree && null != getTitle() && null != ((LibraryTree)tree).getTitle()) {
cmp = COMPARATOR.compare(getTitle(), ((LibraryTree) tree).getTitle());
}
else {
cmp = super.compareTo(tree);
}
if (cmp == 0) { if (cmp == 0) {
return getClass().getSimpleName().compareTo(tree.getClass().getSimpleName()); return getClass().getSimpleName().compareTo(tree.getClass().getSimpleName());
} }
return cmp; return cmp;
} }
public Title getTitle() {
return null;
}
} }

View file

@ -59,7 +59,8 @@ public class SeriesListTree extends FirstLevelTree {
{ {
// TODO: remove empty series tree after update (?) // TODO: remove empty series tree after update (?)
final SeriesInfo info = book.getSeriesInfo(); final SeriesInfo info = book.getSeriesInfo();
return info != null && createSeriesSubTree(info.Title); // TODO: pass series
return info != null && createSeriesSubTree(info.Series.getTitle());
} }
case Removed: case Removed:
// TODO: remove empty series tree (?) // TODO: remove empty series tree (?)
@ -69,7 +70,9 @@ public class SeriesListTree extends FirstLevelTree {
} }
} }
private boolean createSeriesSubTree(String series) { private boolean createSeriesSubTree(String seriesTitle) {
// TODO: pass series as parameter
final Series series = new Series(seriesTitle);
final SeriesTree temp = new SeriesTree(Collection, series, null); final SeriesTree temp = new SeriesTree(Collection, series, null);
int position = Collections.binarySearch(subTrees(), temp); int position = Collections.binarySearch(subTrees(), temp);
if (position >= 0) { if (position >= 0) {

View file

@ -25,25 +25,21 @@ import java.util.List;
import org.geometerplus.zlibrary.core.util.MiscUtil; import org.geometerplus.zlibrary.core.util.MiscUtil;
import org.geometerplus.fbreader.book.*; import org.geometerplus.fbreader.book.*;
import org.geometerplus.fbreader.sort.Title; import org.geometerplus.fbreader.sort.TitledEntity;
import android.widget.Toast; public final class SeriesTree extends TitledEntityTree {
public final Series Series;
public final class SeriesTree extends LibraryTree {
public final Title Series;
public final Author Author; public final Author Author;
SeriesTree(IBookCollection collection, String series, Author author) { SeriesTree(IBookCollection collection, Series series, Author author) {
super(collection); super(collection);
String language = collection.booksForSeries(series).get(0).getLanguage(); Series = series;
Series = new Title(series, language);
Author = author; Author = author;
} }
SeriesTree(LibraryTree parent, String series, Author author, int position) { SeriesTree(LibraryTree parent, Series series, Author author, int position) {
super(parent, position); super(parent, position);
String language = parent.Collection.booksForSeries(series).get(0).getLanguage(); Series = series;
Series = new Title(series, language);
Author = author; Author = author;
} }
@ -72,7 +68,7 @@ public final class SeriesTree extends LibraryTree {
return false; return false;
} }
final SeriesInfo info = book.getSeriesInfo(); final SeriesInfo info = book.getSeriesInfo();
return info != null && Series.getTitle().equals(info.Title); return info != null && Series.equals(info.Series);
} }
@Override @Override
@ -128,9 +124,7 @@ public final class SeriesTree extends LibraryTree {
} }
@Override @Override
public Title getTitle() { public TitledEntity getTitledEntity() {
// TODO Auto-generated method stub
//System.err.println(Series.getSortKey() + Series.getLanguage());
return Series; return Series;
} }
} }

View file

@ -44,7 +44,7 @@ public class TitleListTree extends FirstLevelTree {
final List<Book> book = Collection.books(); final List<Book> book = Collection.books();
final List<String> keys = new ArrayList<String>(); final List<String> keys = new ArrayList<String>();
for (Book b : book) { for (Book b : book) {
keys.add(b.getInfo().getSortKey()); keys.add(b.getSortKey());
} }
if (keys.size() > 9) { if (keys.size() > 9) {
for (String t : keys) { for (String t : keys) {

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2009-2013 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.library;
import org.geometerplus.fbreader.book.IBookCollection;
import org.geometerplus.fbreader.sort.TitledEntity;
import org.geometerplus.fbreader.tree.FBTree;
public abstract class TitledEntityTree extends LibraryTree {
TitledEntityTree(IBookCollection collection) {
super(collection);
}
TitledEntityTree(LibraryTree parent) {
super(parent);
}
TitledEntityTree(LibraryTree parent, int position) {
super(parent, position);
}
protected abstract TitledEntity getTitledEntity();
@Override
public int compareTo(FBTree tree) {
if (tree instanceof TitledEntityTree) {
return getTitledEntity().compareTo(((TitledEntityTree)tree).getTitledEntity());
}
return super.compareTo(tree);
}
}

View file

@ -26,38 +26,33 @@ import java.util.Map;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.os.Build; import android.os.Build;
public class Title { public abstract class TitledEntity implements Comparable<TitledEntity> {
private String myText; private String myTitle;
private String myLanguage;
private String mySortKey; private String mySortKey;
public Title(String title, String language) { public TitledEntity(String title) {
myText = title; myTitle = title;
myLanguage = language;
}
public void setTitle(String title) {
myText = title;
mySortKey = null;
}
public void setLanguage(String language) {
myLanguage = language;
mySortKey = null;
} }
public String getTitle() { public String getTitle() {
return myText; return myTitle;
} }
public String getLanguage() { public void setTitle(String title) {
return myLanguage; myTitle = title;
mySortKey = null;
} }
protected void resetSortKey() {
mySortKey = null;
}
public abstract String getLanguage();
public String getSortKey() { public String getSortKey() {
if (null == mySortKey) { if (null == mySortKey) {
mySortKey = trim(myText, myLanguage); mySortKey = trim(myTitle, getLanguage());
} }
return mySortKey; return mySortKey;
} }
@ -65,12 +60,12 @@ public class Title {
// English articles // English articles
private final static String[] EN_ARTICLES = new String[] { private final static String[] EN_ARTICLES = new String[] {
"the ", "a ", "an " "the ", "a ", "an "
}; };
// French articles // French articles
private final static String[] FR_ARTICLES = new String[] { private final static String[] FR_ARTICLES = new String[] {
"un ", "une ", "le ", "la ", "les ", "du ", "de ", "un ", "une ", "le ", "la ", "les ", "du ", "de ",
"des ", "de la", "l ", "de l " "des ", "de la", "l ", "de l "
}; };
// German articles // German articles
private final static String[] GE_ARTICLES = new String[] { private final static String[] GE_ARTICLES = new String[] {
"das ", "des ", "dem ", "die ", "der ", "den ", "das ", "des ", "dem ", "die ", "der ", "den ",
@ -155,4 +150,8 @@ public class Title {
private static String normalize(String s) { private static String normalize(String s) {
return Normalizer.normalize(s, Normalizer.Form.NFKD); return Normalizer.normalize(s, Normalizer.Form.NFKD);
} }
public int compareTo(TitledEntity entity) {
return getSortKey().compareTo(entity.getSortKey());
}
} }