Organize imports and code cleanup.

This commit is contained in:
openaudible 2018-06-30 15:49:20 -07:00
parent 4c5a9d3031
commit 7b37655531
24 changed files with 150 additions and 205 deletions

View file

@ -53,7 +53,6 @@ public class AudibleScraper {
}
public HtmlPage getPage() {
return page;
}
@ -123,7 +122,7 @@ public class AudibleScraper {
setLoggedIn(false);
}
public void saveCookies() throws IOException {
public void saveCookies() throws IOException {
CookieManager cm = getWebClient().getCookieManager();
ArrayList<BasicClientCookie> list = new ArrayList<>();
@ -216,18 +215,15 @@ public class AudibleScraper {
setPage(submit.click());
boolean ok = checkLoggedIn();
if (!ok)
{
if (!ok) {
HTMLUtil.debugNode(page, "login failed");
LOG.info(page.getUrl());
LOG.info("Login failed, see html files at:"+HTMLUtil.debugFile("submitting-credentials").getAbsolutePath()+" and "+HTMLUtil.debugFile("login failed").getAbsolutePath());
}
else
{
HTMLUtil.debugFile("submitting-credentials").delete();
LOG.info("Login failed, see html files at:" + HTMLUtil.debugFile("submitting-credentials").getAbsolutePath() + " and " + HTMLUtil.debugFile("login failed").getAbsolutePath());
} else {
HTMLUtil.debugFile("submitting-credentials").delete();
}
return ok;
@ -446,7 +442,6 @@ public class AudibleScraper {
}
public Collection<Book> fetchLibraryQuick(HashMap<String, Book> books) throws Exception {
return _fetchLibrary(books);
}
@ -454,14 +449,14 @@ public class AudibleScraper {
public Collection<Book> _fetchLibrary(HashMap<String, Book> existingBooks) throws Exception {
if (page == null)
home();
// LOG.info("Accessing audible library...");
// LOG.info("Accessing audible library...");
HashSet<Book> results = new HashSet<>();
// getWebClient().setJavascriptEnabled(false);
progress.setTask("Scanning your library to get your list of books...", "");
int pageNum = 0;
HtmlElement next = null;
String prev = "";
LibraryParser.instance.howToListenFound=false;
LibraryParser.instance.howToListenFound = false;
while (true) {
progress.throwCanceled();
@ -529,8 +524,7 @@ public class AudibleScraper {
if (newBooks == 0) {
if (LibraryParser.instance.howToListenFound)
{
if (LibraryParser.instance.howToListenFound) {
LOG.error("Looks like your settings need changing. Using your browser, go to Audible: Account: Settings. Then disable: Check for Audible Download Manager ");
throw new AudibleSettingsError();
}
@ -548,9 +542,8 @@ public class AudibleScraper {
return results;
}
private void setPageFilter()
{
try {
private void setPageFilter() {
try {
DomElement purchaseDateFilter = page.getElementByName("purchaseDateFilter");
if (purchaseDateFilter != null && purchaseDateFilter instanceof HtmlSelect) {
HtmlSelect h = (HtmlSelect) purchaseDateFilter;
@ -580,16 +573,14 @@ public class AudibleScraper {
} else {
LOG.info("warning: did not find library filter htmlSelect.");
}
} catch(Throwable th)
{
} catch (Throwable th) {
LOG.error("Unable to set purchaseDateFilter.", th);
}
}
}
public Collection<Book> fetchLibrary() throws Exception {
public Collection<Book> fetchLibrary() throws Exception {
return _fetchLibrary(null);
}
@ -605,7 +596,6 @@ public class AudibleScraper {
}
public boolean hasInfo(Book b) {
BookElement required[] = {BookElement.asin, BookElement.narratedBy};
for (BookElement e : required) {

View file

@ -18,23 +18,21 @@ public enum BookPageParser {
private static final Log LOG = LogFactory.getLog(BookPageParser.class);
// audible uses a lot of cdata. It is useful.
List<String> getCDATATags(String html)
{
List<String> getCDATATags(String html) {
ArrayList<String> list = new ArrayList<>();
String startTag="<![CDATA[";
String startTag = "<![CDATA[";
String endTag = "//]]>";
int ch = 0;
for (;;)
{
for (; ; ) {
int start = html.indexOf(startTag, ch);
if (start == -1) break;
int end = html.indexOf(endTag, ch);
assert(end!=-1);
assert (end != -1);
if (end == -1) break;
String cdata = html.substring(start+startTag.length(), end).trim();
String cdata = html.substring(start + startTag.length(), end).trim();
list.add(cdata);
ch = end+endTag.length();
ch = end + endTag.length();
}
@ -46,21 +44,17 @@ public enum BookPageParser {
// HTMLUtil.debugNode(page, "book_info");
String xml = page.asXml();
List<String> cdataList = getCDATATags(xml);
for (String cd:cdataList)
{
if (cd.startsWith("["))
{
for (String cd : cdataList) {
if (cd.startsWith("[")) {
cd = cd.replace("\n", ""); // getting parse errors.
try {
JSONArray jsonArray = new JSONArray(cd);
for (int x=0;x<jsonArray.length();x++)
{
for (int x = 0; x < jsonArray.length(); x++) {
JSONObject obj = jsonArray.getJSONObject(x);
extractFromJSON(obj, b);
}
}catch(Throwable th)
{
} catch (Throwable th) {
LOG.info(cd);
LOG.error("cdata json parse error", th);
}
@ -83,14 +77,12 @@ public enum BookPageParser {
// LOG.info(obj.toString(2));
for (String k:obj.keySet())
{
for (String k : obj.keySet()) {
Object value = obj.get(k);
String str = value!=null ? value.toString():"";
String str = value != null ? value.toString() : "";
BookElement elem = null;
switch(k)
{
switch (k) {
case "description":
elem = BookElement.summary; // our summary is the description
break;
@ -123,10 +115,10 @@ public enum BookPageParser {
case "aggregateRating":
JSONObject rating = obj.getJSONObject(k);
double rvalue = rating.optDouble("ratingValue", 0);
int rcount = rating.optInt("ratingCount",0);
if (rvalue>0)
b.setRating_average(rvalue);
if (rcount>0)
int rcount = rating.optInt("ratingCount", 0);
if (rvalue > 0)
b.setRating_average(rvalue);
if (rcount > 0)
b.setRating_count(rcount);
break;
case "name":
@ -140,8 +132,7 @@ public enum BookPageParser {
break;
}
if (elem!=null && !str.isEmpty())
{
if (elem != null && !str.isEmpty()) {
if (!str.equals(b.get(elem))) {
LOG.info("set " + elem + " from " + b.get(elem) + " to " + str);
b.set(elem, str);
@ -163,15 +154,13 @@ public enum BookPageParser {
// array of 'person' objects.
private String personToString(JSONArray arr) {
String out = "";
for (int x=0;x<arr.length();x++)
{
for (int x = 0; x < arr.length(); x++) {
JSONObject p = arr.getJSONObject(x);
assert(p.getString("@type").equals("Person"));
String name = p.optString("name","");
if (!name.isEmpty())
{
assert (p.getString("@type").equals("Person"));
String name = p.optString("name", "");
if (!name.isEmpty()) {
if (!out.isEmpty())
out+=",";
out += ",";
out += name;
}
}

View file

@ -7,6 +7,8 @@ import org.openaudible.AudibleAccountPrefs;
*/
public interface ConnectionListener {
void connectionChanged(boolean connected);
AudibleAccountPrefs getAccountPrefs(AudibleAccountPrefs in);
void loginFailed(String url, String html);
}

View file

@ -52,8 +52,7 @@ public class ConnectionNotifier extends EventNotifier<ConnectionListener> implem
public boolean isDisconnected() {
return getState() == State.Disconnected;
}
// not connected is unknown.
// connected means in account
@ -63,15 +62,13 @@ public class ConnectionNotifier extends EventNotifier<ConnectionListener> implem
}
@Override
public void loginFailed(String url, String html)
{
@Override
public void loginFailed(String url, String html) {
for (ConnectionListener l : getListeners()) {
l.loginFailed(url, html);
}
}
}
}

View file

@ -105,15 +105,12 @@ public enum LibraryParser {
continue; // skip header row.
Book b = parseLibraryRow(r);
if (b != null)
{
if (b != null) {
String chk = b.checkBook();
if (chk.isEmpty())
{
if (chk.isEmpty()) {
list.add(b);
} else
{
LOG.info("Warning, problem parsing book: "+b+" error: "+chk);
} else {
LOG.info("Warning, problem parsing book: " + b + " error: " + chk);
}
}
@ -133,8 +130,7 @@ public enum LibraryParser {
String xml = Util.cleanString(r.asXml());
if (r.getCells().size() == 0)
return null; // empty row.
if (xml.contains("/howtolisten"))
{
if (xml.contains("/howtolisten")) {
// this is a problem.. settings need to be changed.
howToListenFound = true;
}
@ -155,8 +151,8 @@ public enum LibraryParser {
if (!debugString.isEmpty()) {
int count = Util.substringCount(debugString, xml);
if (count>0)
LOG.info("Found debugString: " + count + " "+debugString);
if (count > 0)
LOG.info("Found debugString: " + count + " " + debugString);
}
if (debug) HTMLUtil.debugNode(r, "cur_row");
@ -267,7 +263,7 @@ public enum LibraryParser {
HashMap<String, String> args = Util.urlGetArgs(url);
for (String k : args.keySet()) {
BookElement elem = BookElement.findByName(k);
if (elem != null) {
b.set(elem, args.get(k));

View file

@ -69,8 +69,8 @@ public class Book implements Comparable<Book>, Serializable {
}
public boolean equals(Book that) {
if (that==null) return false;
if (this==that) return true;
if (that == null) return false;
if (this == that) return true;
boolean e1 = this.getProduct_id().equals(that.getProduct_id());
return e1;
}
@ -208,7 +208,7 @@ public class Book implements Comparable<Book>, Serializable {
}
public void setRating_average(double rating_average) {
set(BookElement.rating_average, ""+ rating_average);
set(BookElement.rating_average, "" + rating_average);
}
public String getRating_count() {
@ -218,8 +218,9 @@ public class Book implements Comparable<Book>, Serializable {
public void setRating_count(String rating_count) {
set(BookElement.rating_count, rating_count);
}
public void setRating_count(int rating_count) {
set(BookElement.rating_count, ""+rating_count);
set(BookElement.rating_count, "" + rating_count);
}
public String getRelease_date() {

View file

@ -10,8 +10,7 @@ public enum BookElement {
try {
return BookElement.valueOf(s);
} catch (Throwable th) {
switch(s)
{
switch (s) {
case "title":
return shortTitle;
case "DownloadType":

View file

@ -91,8 +91,7 @@ public class ConvertJob implements IQueueJob, LineListener {
}
}
} else
{
} else {
stdErr.accept(s);
}
@ -141,7 +140,6 @@ public class ConvertJob implements IQueueJob, LineListener {
}
args.add("-codec:a");
args.add("libmp3lame"); // see: https://trac.ffmpeg.org/wiki/Encode/MP3
args.add("-qscale:a"); // https://trac.ffmpeg.org/wiki/Encode/MP3
@ -224,7 +222,7 @@ public class ConvertJob implements IQueueJob, LineListener {
private void addTag(ArrayList<String> args, String key, String value) {
if (!value.isEmpty()) {
args.add("-metadata");
args.add("key="+key);
args.add("key=" + key);
value = value.replace("\"", "");
args.add(value);
@ -251,7 +249,6 @@ public class ConvertJob implements IQueueJob, LineListener {
}
public void renameMP3() throws IOException {
boolean ok = temp.renameTo(mp3);
if (!ok) {
@ -259,7 +256,7 @@ public class ConvertJob implements IQueueJob, LineListener {
Files.copy(temp.toPath(), mp3.toPath());
temp.delete();
if (!mp3.exists())
throw new IOException("Error renaming: " + temp.getAbsolutePath() + " size ["+temp.length()+"] to " + mp3.getAbsolutePath()+" mp3 exists="+mp3.exists());
throw new IOException("Error renaming: " + temp.getAbsolutePath() + " size [" + temp.length() + "] to " + mp3.getAbsolutePath() + " mp3 exists=" + mp3.exists());
}
}
@ -278,7 +275,7 @@ public class ConvertJob implements IQueueJob, LineListener {
if (progress != null)
progress.setTask(null, "Complete");
} catch (Exception e) {
LOG.error("Error converting book:"+book, e);
LOG.error("Error converting book:" + book, e);
if (progress != null) {
progress.setSubTask(e.getMessage());
}

View file

@ -17,7 +17,6 @@ import org.openaudible.util.SimpleProcess;
import org.openaudible.util.SimpleProcess.Results;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public abstract class GUI implements ITranslatable {
@ -165,22 +164,20 @@ public abstract class GUI implements ITranslatable {
public static void explore(File m) {
ArrayList<String>cmdLine = new ArrayList<>();
switch(Platform.getPlatform())
{
case mac:
cmdLine.add("open");
ArrayList<String> cmdLine = new ArrayList<>();
if (!m.isDirectory())
{
cmdLine.add("-R");
switch (Platform.getPlatform()) {
case mac:
cmdLine.add("open");
if (!m.isDirectory()) {
cmdLine.add("-R");
}
break;
case win:
cmdLine.add("Explorer ");
cmdLine.add("/select,");
break;
case linux:
cmdLine.add("gnome-open");
@ -188,21 +185,20 @@ public abstract class GUI implements ITranslatable {
break;
}
if (cmdLine.isEmpty()) return;
try {
cmdLine.add(m.getAbsolutePath());
SimpleProcess p = new SimpleProcess(cmdLine);
p.run();
Results r = p.getResults();
cmdLine.add(m.getAbsolutePath());
SimpleProcess p = new SimpleProcess(cmdLine);
p.run();
Results r = p.getResults();
} catch (Throwable e) {
e.printStackTrace();
}
} catch (Throwable e) {
e.printStackTrace();
}
}

View file

@ -15,7 +15,7 @@ public abstract class SWTAsync implements Runnable {
public static boolean quit = false;
public static boolean useStack = Version.appDebug;
public static boolean useTimer = Version.appDebug;
static Hashtable <String, TimeStats>timeResults = new Hashtable<>(); //
static Hashtable<String, TimeStats> timeResults = new Hashtable<>(); //
static long block_count = 0;
Exception stack = null;
final String taskName;

View file

@ -7,9 +7,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.openaudible.Audible;
import org.openaudible.AudibleAccountPrefs;
@ -31,7 +29,6 @@ import org.openaudible.desktop.swt.manager.views.PasswordDialog;
import org.openaudible.desktop.swt.manager.views.StatusPanel;
import org.openaudible.feeds.pagebuilder.WebPage;
import org.openaudible.util.HTMLUtil;
import org.openaudible.util.Platform;
import org.openaudible.util.TimeToSeconds;
import org.openaudible.util.queues.IQueueJob;
import org.openaudible.util.queues.IQueueListener;
@ -337,18 +334,17 @@ public class AudibleGUI implements BookListener, ConnectionListener {
MessageBoxFactory.showGeneral(null, 0, "Log in via web browser...", "Unable to connect right now.\n\nTry logging on to Audible from this web page and try again.\n\nIf this keeps ");
} catch(AudibleSettingsError ase){
} catch (AudibleSettingsError ase) {
String msg = "OpenAudible detected a problem trying to get your book list.\n\n";
msg += "Please change your settings in "+audible.getAudibleURL()+".\n"+
msg += "Please change your settings in " + audible.getAudibleURL() + ".\n" +
"Log into your audible account, click on the Account link, then settings.\n" +
" "+browseSettings()+"\n"+
"Uncheck (disable) the setting marked: Check for Audible Download Manager\n\n"+
"After changing the setting, try again. \n"+
" " + browseSettings() + "\n" +
"Uncheck (disable) the setting marked: Check for Audible Download Manager\n\n" +
"After changing the setting, try again. \n" +
"(You may also want to check for an update or other known problems.)";
MessageBoxFactory.showError(null, "Audible settings need to be changed", msg);
}
catch (Throwable e) {
} catch (Throwable e) {
LOG.info("Error refreshing library", e);
if (!wasCanceled()) {
@ -1174,21 +1170,19 @@ public class AudibleGUI implements BookListener, ConnectionListener {
}
@Override
public void loginFailed(String url, String html)
{
@Override
public void loginFailed(String url, String html) {
SWTAsync.slow(new SWTAsync("Login problem...") {
public void task() {
String message = "There was a problem logging in... Try to view the page in the OpenAudible Browser?";
boolean ok = MessageBoxFactory.showGeneralYesNo(null, "Trouble logging in", message);
if (ok)
browse(url);
String message = "There was a problem logging in... Try to view the page in the OpenAudible Browser?";
boolean ok = MessageBoxFactory.showGeneralYesNo(null, "Trouble logging in", message);
if (ok)
browse(url);
}
});
}
}
}

View file

@ -22,7 +22,7 @@ public enum VersionCheck {
public void checkForUpdate(Shell shell, boolean verbose) {
JSONObject obj = versionCheck();
String msg = obj.optString("msg");
String title = obj.optString("title","Version Check");
String title = obj.optString("title", "Version Check");
int diff = obj.optInt("diff", 0);
if (diff < 0) {
@ -50,7 +50,7 @@ public enum VersionCheck {
url += "&version=" + Version.appVersion;
// url += "&count=" + audible.getBookCount();
LOG.info("versionCheck: " + url);
return HTTPGet.instance.getJSON(url);
return HTTPGet.instance.getJSON(url);
}
/**
@ -100,27 +100,25 @@ public enum VersionCheck {
if (diff < 0) {
title = "Update Available";
msg = "An update is available!\nYour version: " + Version.appVersion + "\nRelease Version:" + releaseVersion;
if (obj.optBoolean("required", false))
{
if (obj.optBoolean("required", false)) {
msg += "\nThis upgrade is required. Old versions no longer supported.";
CommandCenter.instance.expiredApp = true;
}
msg += "\n"+obj.optString("old_news", "");
msg += "\n" + obj.optString("old_news", "");
} else if (diff > 0) {
title = "Using Pre-release";
msg = "You appear to be using a pre-release version\nYour version: " + Version.appVersion + "\nLatest Version:" + releaseVersion;
msg += "\n"+obj.optString("pre_release_news", "");
msg += "\n" + obj.optString("pre_release_news", "");
} else {
title = "No update at this time";
msg = "Using the latest release version.";
msg += "\n"+obj.optString("current_news", "");
msg += "\n" + obj.optString("current_news", "");
// allow a news field
}
if (obj.has("kill"))
{
msg +="\n"+obj.getString("kill");
if (obj.has("kill")) {
msg += "\n" + obj.getString("kill");
CommandCenter.instance.expiredApp = true;
}

View file

@ -29,7 +29,7 @@ import org.openaudible.desktop.swt.util.shop.WidgetShop;
public class CommandCenter {
public final static Log logger = LogFactory.getLog(CommandCenter.class);
public static CommandCenter instance;
public boolean expiredApp =false;
public boolean expiredApp = false;
boolean confirmQuit = true;
boolean confirmSave = true;
private Clipboard cb;
@ -289,7 +289,7 @@ public class CommandCenter {
public boolean getEnabled(Command c) {
if (expiredApp)
return c==Command.Quit || c==Command.Check_For_Update || c==Command.About;
return c == Command.Quit || c == Command.Check_For_Update || c == Command.About;
switch (c) {
case Convert:
return AudibleGUI.instance.canConvert();

View file

@ -109,16 +109,15 @@ public class AudibleBrowser {
AudibleBrowser app = new AudibleBrowser(shell, url);
shell.open();
return app;
} catch(Throwable th)
{
} catch (Throwable th) {
shell.dispose();
String err = "Uh oh. An error occurred opening the internal web browser. \n\nThis means your system may not be compatible with this version of OpenAudible.\n\nCheck the console window and copy this error and stack trace below. \n"+
String err = "Uh oh. An error occurred opening the internal web browser. \n\nThis means your system may not be compatible with this version of OpenAudible.\n\nCheck the console window and copy this error and stack trace below. \n" +
"Create or view existing code issues at:\nhttps://github.com/openaudible/openaudible/issues \n";
String m = ""+ th.getMessage();
String m = "" + th.getMessage();
m = m.replace("No more handles", "");
m = m.replace("[", " ");
m = m.replace("]", " ");
err += "\n\nError code:\n"+m.trim();
err += "\n\nError code:\n" + m.trim();
logger.error(err, th);
MessageBoxFactory.showError(null, "Error opening internal web browser", err);
return null;
@ -267,11 +266,9 @@ public class AudibleBrowser {
// https://www.audible.com/
String host = "www.audible.com";
if (u.startsWith("http"))
{
if (u.startsWith("http")) {
String[] parts = u.split("/");
if (parts!=null && parts.length>2)
{
if (parts != null && parts.length > 2) {
if (parts[2].contains("audible"))
host = parts[2];
}
@ -287,7 +284,7 @@ public class AudibleBrowser {
cookies = list;
} else
logger.info("Expected url to include audible, instead: " + u);
logger.info("cookieCallback: " + list.size());
return null;

View file

@ -124,11 +124,10 @@ public class BookTable extends EnumTable<Book, BookTableColumn> implements BookL
public String getColumnDisplayable(BookTableColumn column, Book b) {
String s;
if (column.equals(BookTableColumn.Time))
{
if (column.equals(BookTableColumn.Time)) {
//long seconds = TimeToSeconds.parseTimeStringToSeconds(b.getDuration());
// TimeToSeconds.secondsToTime()
// TimeToSeconds.secondsToTime()
return b.getDuration();
}
@ -137,7 +136,6 @@ public class BookTable extends EnumTable<Book, BookTableColumn> implements BookL
}
public Comparable<?> getColumnComparable(BookTableColumn column, Book b) {
switch (column) {
case Author:

View file

@ -144,12 +144,11 @@ public class StatusPanel extends GridComposite implements BookListener, Connecti
}
}
@Override
public void loginFailed(String url, String html)
{
// TODO Auto-generated method stub
}
@Override
public void loginFailed(String url, String html) {
// TODO Auto-generated method stub
}
}

View file

@ -124,9 +124,8 @@ public class FontShop {
Display display = Display.getCurrent();
int sizeAdjust = 0;
Font fontCopy = null;
if (Platform.isLinux())
{
sizeAdjust -=2;
if (Platform.isLinux()) {
sizeAdjust -= 2;
}
switch (id) {

View file

@ -29,8 +29,8 @@ public class DownloadQueue extends ThreadedQueue<Book> {
}
public boolean canAdd(Book b) {
assert(b.has(BookElement.user_id));
assert(b.has(BookElement.product_id));
assert (b.has(BookElement.user_id));
assert (b.has(BookElement.product_id));
if (!super.canAdd(b)) return false;
if (!b.has(BookElement.user_id)) return false;
if (!b.has(BookElement.product_id)) return false;

View file

@ -90,11 +90,10 @@ public class HTMLUtil {
return null;
}
public static File debugFile(String what)
{
public static File debugFile(String what) {
return new File(Directories.getTmpDir(), what);
}
public static String debugNode(DomNode p, String what) {
String xml = "";

View file

@ -25,7 +25,7 @@ public enum Platform {
return getPlatform().equals(win);
}
public static boolean isLinux() {
public static boolean isLinux() {
return getPlatform().equals(linux);
}
}
}

View file

@ -86,10 +86,10 @@ public class SimpleProcess {
} finally {
if (is!=null)
is.finish();
if (err!=null)
err.finish();
if (is != null)
is.finish();
if (err != null)
err.finish();
}

View file

@ -11,26 +11,21 @@ public class TimeToSeconds {
throw new NumberFormatException("parseTimeString empty str");
int h = 0;
int m=0, s=0;
if (str.contains("m") || str.contains("h") || str.contains("s"))
{
for (String unit:str.split(" "))
{
if (unit.contains("m"))
{
int m = 0, s = 0;
if (str.contains("m") || str.contains("h") || str.contains("s")) {
for (String unit : str.split(" ")) {
if (unit.contains("m")) {
unit = unit.replace("m", "");
m = Integer.parseInt(unit.trim());
} else
if (unit.contains("h"))
{
} else if (unit.contains("h")) {
unit = unit.replace("h", "");
h = Integer.parseInt(unit.trim());
} else
if (unit.contains("s"))
{
} else if (unit.contains("s")) {
unit = unit.replace("s", "");
s = Integer.parseInt(unit.trim());
} else { throw new NumberFormatException("invalid time format:"+str); }
} else {
throw new NumberFormatException("invalid time format:" + str);
}
}
} else {
String units[] = str.split(":");
@ -53,13 +48,12 @@ public class TimeToSeconds {
throw new NumberFormatException("parseTimeString failed:" + str);
}
if (m>60)
if (m > 60)
throw new NumberFormatException("parseTimeString minute > 60:" + str);
if (s>60)
if (s > 60)
throw new NumberFormatException("parseTimeString second > 60:" + str);
}
if (m < 0 || s < 0 || h < 0)

View file

@ -21,13 +21,13 @@ import javax.xml.bind.annotation.XmlValue;
/**
* It has one optional attribute, domain, a string that identifies a categorization taxonomy.
*
* <p>
* The value of the element is a forward-slash-separated string that identifies a hierarchic location in the indicated taxonomy.
* Processors may establish conventions for the interpretation of categories. Two examples are provided below:
*
* <category>Grateful Dead</category>
* <category domain="http://www.fool.com/cusips">MSFT</category>
*
* <p>
* You may include as many category elements as you need to, for different domains, and to have an item cross-referenced in different parts of the same domain.
*/
public class Category {

View file

@ -32,7 +32,7 @@ import java.util.List;
/**
* Built from the following specifications:
*
* <p>
* RSS Spec: http://cyber.law.harvard.edu/rss/rss.html
* ATOM Spec: https://tools.ietf.org/html/rfc4287
* Itunes Spec: http://www.apple.com/itunes/podcasts/specs.html