diff --git a/build.gradle b/build.gradle index 915c5d9..748367f 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,10 @@ dependencies { // JAXB API only implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3' + + // https://central.sonatype.com/artifact/com.google.guava/guava/ + implementation 'com.google.guava:guava:31.1-jre' + //JAXB RI, Jakarta XML Binding runtimeOnly 'com.sun.xml.bind:jaxb-impl:2.3.8' diff --git a/src/main/java/christophedelory/content/Content.java b/src/main/java/christophedelory/content/Content.java index 282a53f..7c9d3ce 100644 --- a/src/main/java/christophedelory/content/Content.java +++ b/src/main/java/christophedelory/content/Content.java @@ -353,7 +353,7 @@ public void setHeight(final int height) */ public boolean isValid() { - return (_connected == null) ? false : _connected.booleanValue(); + return _connected != null && _connected.booleanValue(); } /** @@ -362,7 +362,6 @@ public boolean isValid() * @throws IllegalArgumentException if the URL is not absolute. * @throws MalformedURLException if a protocol handler for the URL could not be found, or if some other error occurred while constructing the URL. * @throws IOException if any I/O error occurs. - * @throws SocketTimeoutException if the timeout expires before the connection can be established. * @see #getURL */ public void connect() throws IOException @@ -444,7 +443,7 @@ public void connect() throws IOException @Override public boolean equals(final Object obj) { - return (obj == null) ? false : _urlString.equals(obj.toString()); + return obj != null && _urlString.equals(obj.toString()); } /** diff --git a/src/main/java/christophedelory/content/type/ContentType.java b/src/main/java/christophedelory/content/type/ContentType.java index 6d6aef9..d9329e7 100644 --- a/src/main/java/christophedelory/content/type/ContentType.java +++ b/src/main/java/christophedelory/content/type/ContentType.java @@ -141,6 +141,7 @@ public PlayerSupport[] getPlayerSupports() * @see #setDescription * @see FileFilter#getDescription */ + @Override public String getDescription() { return _description; @@ -191,7 +192,7 @@ public boolean matchExtension(final String pattern) @Override public boolean accept(final File f) { - return (f.isDirectory()) ? true : matchExtension(f.getName()); // Throws NullPointerException if f is null. + return f.isDirectory() || matchExtension(f.getName()); // Throws NullPointerException if f is null. } /** diff --git a/src/main/java/christophedelory/content/type/ContentTypesFileFilter.java b/src/main/java/christophedelory/content/type/ContentTypesFileFilter.java index 902669c..d978938 100644 --- a/src/main/java/christophedelory/content/type/ContentTypesFileFilter.java +++ b/src/main/java/christophedelory/content/type/ContentTypesFileFilter.java @@ -103,6 +103,7 @@ public List getContentTypes() * @return a description. Shall not be null. * @see FileFilter#getDescription */ + @Override public String getDescription() { final StringBuilder sb = new StringBuilder(_title); diff --git a/src/main/java/christophedelory/io/IOUtils.java b/src/main/java/christophedelory/io/IOUtils.java index 4265fb8..403d01e 100644 --- a/src/main/java/christophedelory/io/IOUtils.java +++ b/src/main/java/christophedelory/io/IOUtils.java @@ -24,9 +24,11 @@ */ package christophedelory.io; +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.IOException; import java.io.StringWriter; /** @@ -51,7 +53,7 @@ public static String toString(final InputStream in, final String encoding) throw if (encoding == null) { - reader = new InputStreamReader(in); // Throws NullPointerException if in is null. + reader = new InputStreamReader(in, UTF_8); // Throws NullPointerException if in is null. } else { @@ -62,7 +64,7 @@ public static String toString(final InputStream in, final String encoding) throw final char[] buffer = new char[512]; int nb = 0; - while (-1 != (nb = reader.read(buffer))) // May throw IOException. + while ((nb = reader.read(buffer)) != -1) // May throw IOException. { writer.write(buffer, 0, nb); } diff --git a/src/main/java/christophedelory/lizzy/AddToPlaylist.java b/src/main/java/christophedelory/lizzy/AddToPlaylist.java index 8b9b6ef..ebd8ba6 100644 --- a/src/main/java/christophedelory/lizzy/AddToPlaylist.java +++ b/src/main/java/christophedelory/lizzy/AddToPlaylist.java @@ -109,49 +109,49 @@ public static void main(final String[] args) throws Exception * The playlist type, if specified. */ @Option(name="-t",usage="The output playlist type\nAllowed values: see below",metaVar="type") - private volatile String _type = null; + private String _type = null; /** * Specifies if the content metadata shall be fetched, if possible. */ @Option(name="-m",usage="Fetch if possible the media content metadata") - private volatile boolean _fetchContentMetadata = false; + private boolean _fetchContentMetadata = false; /** * The sub-directories shall be recursively scanned. */ @Option(name="-r",usage="Recursively add sub-directories contents") - private volatile boolean _recursive = false; + private boolean _recursive = false; /** * The output file or URL. */ @Option(name="-o",usage="The output file or URL\nIf missing, a file save dialog is prompted\nIf the output playlist type is not specified (-t), it will be inferred from the output file name extension",metaVar="file/URL") - private volatile String _output = null; + private String _output = null; /** * Specifies that the marshalled M3U playlist must use the Extension M3U format. */ @Option(name="-m3u:ext",usage="The output M3U playlist must use the Extension M3U format") - private volatile boolean _extM3U = false; + private boolean _extM3U = false; /** * Specifies that the output RSS shall make use of the RSS Media extension. */ @Option(name="-rss:media",usage="The output RSS playlist must use the RSS Media format") - private volatile boolean _useRSSMedia = false; + private boolean _useRSSMedia = false; /** * Specifies the disk identifier of the output PLP playlist. */ @Option(name="-plp:disk",usage="The disk identifier of the output PLP playlist\nExamples: HARP, HDD",metaVar="disk") - private volatile String _diskSpecifier = null; + private String _diskSpecifier = null; /** * The list of input files or directories. */ @Argument(usage="One or more files or directories to add to the output playlist",metaVar="input-files(s)",required=true) - private volatile ArrayList _arguments = new ArrayList(); // NOPMD Avoid using implementation types; use the interface instead + private ArrayList _arguments = new ArrayList<>(); // NOPMD Avoid using implementation types; use the interface instead /** * The default no-arg constructor shall not be publicly available. @@ -493,7 +493,7 @@ else if (file.isFile()) // May throw SecurityException. sb.insert(0, '/'); // Shall not throw StringIndexOutOfBoundsException. final String previousFileName = previousFile.getName(); - if (!"/".equals(previousFileName) && !"\\".equals(previousFileName)) + if (!previousFileName.equals("/") && !previousFileName.equals("\\")) { sb.insert(0, previousFileName); // Shall not throw StringIndexOutOfBoundsException. } diff --git a/src/main/java/christophedelory/lizzy/ContentTypeInfo.java b/src/main/java/christophedelory/lizzy/ContentTypeInfo.java index 6b75ccb..5aa0afa 100644 --- a/src/main/java/christophedelory/lizzy/ContentTypeInfo.java +++ b/src/main/java/christophedelory/lizzy/ContentTypeInfo.java @@ -218,7 +218,7 @@ public static void main(final String[] args) sb.append(""); } - System.out.println(sb.toString()); // NOPMD System.out.print is used + System.out.println(sb); // NOPMD System.out.print is used } /** diff --git a/src/main/java/christophedelory/lizzy/FetchContentMetadata.java b/src/main/java/christophedelory/lizzy/FetchContentMetadata.java index 28bbafa..c6b7087 100644 --- a/src/main/java/christophedelory/lizzy/FetchContentMetadata.java +++ b/src/main/java/christophedelory/lizzy/FetchContentMetadata.java @@ -61,7 +61,7 @@ public void setConnect(final boolean connect) } @Override - public void beginVisitMedia(final Media target) throws Exception + public void beginVisitMedia(final Media target) { if (target.getSource() != null) { diff --git a/src/main/java/christophedelory/lizzy/PlaylistToString.java b/src/main/java/christophedelory/lizzy/PlaylistToString.java index 7681f16..9e8c5c4 100644 --- a/src/main/java/christophedelory/lizzy/PlaylistToString.java +++ b/src/main/java/christophedelory/lizzy/PlaylistToString.java @@ -54,12 +54,9 @@ public class PlaylistToString extends BasePlaylistVisitor /** * Builds a new playlist visitor. - * @see BasePlaylistVisitor#BasePlaylistVisitor */ public PlaylistToString() { - super(); - _sb = new StringBuilder(); _indent = 0; _debug = false; @@ -83,7 +80,7 @@ public String toString() } @Override - public void beginVisitParallel(final Parallel target) throws Exception + public void beginVisitParallel(final Parallel target) { addIndent(); _sb.append("PARALLEL(x"); @@ -101,13 +98,13 @@ public void beginVisitParallel(final Parallel target) throws Exception } @Override - public void endVisitParallel(final Parallel target) throws Exception + public void endVisitParallel(final Parallel target) { _indent -= 2; } @Override - public void beginVisitSequence(final Sequence target) throws Exception + public void beginVisitSequence(final Sequence target) { addIndent(); _sb.append("SEQUENCE(x"); @@ -125,13 +122,13 @@ public void beginVisitSequence(final Sequence target) throws Exception } @Override - public void endVisitSequence(final Sequence target) throws Exception + public void endVisitSequence(final Sequence target) { _indent -= 2; } @Override - public void beginVisitMedia(final Media target) throws Exception + public void beginVisitMedia(final Media target) { addIndent(); _sb.append("MEDIA(x"); diff --git a/src/main/java/christophedelory/lizzy/Transcode.java b/src/main/java/christophedelory/lizzy/Transcode.java index 9c29d80..8dfac75 100644 --- a/src/main/java/christophedelory/lizzy/Transcode.java +++ b/src/main/java/christophedelory/lizzy/Transcode.java @@ -24,30 +24,30 @@ */ package christophedelory.lizzy; +import static java.nio.charset.StandardCharsets.UTF_8; + +import christophedelory.playlist.Playlist; +import christophedelory.playlist.SpecificPlaylist; +import christophedelory.playlist.SpecificPlaylistFactory; +import christophedelory.playlist.SpecificPlaylistProvider; +import christophedelory.playlist.m3u.M3U; +import christophedelory.playlist.plp.PLP; +import christophedelory.playlist.rss.RSSProvider; +import christophedelory.xml.Version; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; -import java.net.MalformedURLException; import java.util.ArrayList; - import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; -import christophedelory.playlist.Playlist; -import christophedelory.playlist.SpecificPlaylist; -import christophedelory.playlist.SpecificPlaylistFactory; -import christophedelory.playlist.SpecificPlaylistProvider; -import christophedelory.playlist.m3u.M3U; -import christophedelory.playlist.plp.PLP; -import christophedelory.playlist.rss.RSSProvider; -import christophedelory.xml.Version; - /** * Converts a given playlist file to a specified format. * @since 0.2.0 @@ -73,7 +73,7 @@ public static void buildCurrentVersion(final String resourceName) throws Excepti final URL url = Version.class.getClassLoader().getResource(resourceName); // May throw SecurityException. Throws NullPointerException if resourceName is null. if (url != null) { - final BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); // May throw IOException. Throws NullPointerException if url is null. + final BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8)); // May throw IOException. Throws NullPointerException if url is null. final String version = reader.readLine(); // May throw IOException. Version.CURRENT = Version.valueOf(version); // Throws NullPointerException if version is null. Should not throw IllegalArgumentException, IndexOutOfBoundsException, NumberFormatException. @@ -126,55 +126,55 @@ public static void main(final String[] args) throws Exception * The playlist type, if specified. */ @Option(name="-t",usage="The output playlist type\nAllowed values: see below\nIf missing, the input playlist type is used",metaVar="type") - private volatile String _type = null; + private String _type = null; /** * Specifies if the intermediate generic playlist shall be displayed or not. */ @Option(name="-g",usage="Show the intermediate generic playlist") - private volatile boolean _showGenericPlaylist = false; + private boolean _showGenericPlaylist = false; /** * Specifies if the (parsed) input playlist shall be displayed or not. */ @Option(name="-i",usage="Show the parsed input playlist") - private volatile boolean _showInputPlaylist = false; + private boolean _showInputPlaylist = false; /** * Specifies if the content metadata shall be fetched, if possible. */ @Option(name="-m",usage="Fetch if possible the media content metadata") - private volatile boolean _fetchContentMetadata = false; + private boolean _fetchContentMetadata = false; /** * The output file or URL. */ @Option(name="-o",usage="The output file or URL\nIf missing, stdout is used\nIf the output playlist type is not specified (-t), it will be inferred from the output file name extension",metaVar="file/URL") - private volatile String _output = null; + private String _output = null; /** * Specifies that the marshalled M3U playlist must use the Extension M3U format. */ @Option(name="-m3u:ext",usage="The output M3U playlist must use the Extension M3U format") - private volatile boolean _extM3U = false; + private boolean _extM3U = false; /** * Specifies that the output RSS shall make use of the RSS Media extension. */ @Option(name="-rss:media",usage="The output RSS playlist must use the RSS Media format") - private volatile boolean _useRSSMedia = false; + private boolean _useRSSMedia = false; /** * Specifies the disk identifier of the output PLP playlist. */ @Option(name="-plp:disk",usage="The disk identifier of the output PLP playlist\nExamples: HARP, HDD",metaVar="disk") - private volatile String _diskSpecifier = null; + private String _diskSpecifier = null; /** * The input file or URL. */ @Argument(usage="The input playlist file or URL",metaVar="input-playlist",required=true) - private volatile ArrayList _arguments = new ArrayList(); // NOPMD Avoid using implementation types; use the interface instead + private ArrayList _arguments = new ArrayList(); // NOPMD Avoid using implementation types; use the interface instead /** * The default no-arg constructor shall not be publicly available. diff --git a/src/main/java/christophedelory/player/PlayerSupport.java b/src/main/java/christophedelory/player/PlayerSupport.java index 9765177..7746b6c 100644 --- a/src/main/java/christophedelory/player/PlayerSupport.java +++ b/src/main/java/christophedelory/player/PlayerSupport.java @@ -55,7 +55,7 @@ public enum Player VLC_MEDIA_PLAYER, WINAMP, WINDOWS_MEDIA_PLAYER, - }; + } /** * Returns a string representation of the specified player. diff --git a/src/main/java/christophedelory/playlist/AbstractPlaylistProvider.java b/src/main/java/christophedelory/playlist/AbstractPlaylistProvider.java index 0ff6931..a6f180b 100644 --- a/src/main/java/christophedelory/playlist/AbstractPlaylistProvider.java +++ b/src/main/java/christophedelory/playlist/AbstractPlaylistProvider.java @@ -8,7 +8,7 @@ public abstract class AbstractPlaylistProvider implements SpecificPlaylistProvider { - protected Log logger; + protected final Log logger; public AbstractPlaylistProvider(Class clazz) { this.logger = LogFactory.getLog(clazz); diff --git a/src/main/java/christophedelory/playlist/BasePlaylistVisitor.java b/src/main/java/christophedelory/playlist/BasePlaylistVisitor.java index 0a38746..48338a6 100644 --- a/src/main/java/christophedelory/playlist/BasePlaylistVisitor.java +++ b/src/main/java/christophedelory/playlist/BasePlaylistVisitor.java @@ -32,49 +32,49 @@ public class BasePlaylistVisitor implements PlaylistVisitor { @Override - public void beginVisitPlaylist(final Playlist target) throws Exception + public void beginVisitPlaylist(final Playlist target) { // No-op. } @Override - public void endVisitPlaylist(final Playlist target) throws Exception + public void endVisitPlaylist(final Playlist target) { // No-op. } @Override - public void beginVisitParallel(final Parallel target) throws Exception + public void beginVisitParallel(final Parallel target) { // No-op. } @Override - public void endVisitParallel(final Parallel target) throws Exception + public void endVisitParallel(final Parallel target) { // No-op. } @Override - public void beginVisitSequence(final Sequence target) throws Exception + public void beginVisitSequence(final Sequence target) { // No-op. } @Override - public void endVisitSequence(final Sequence target) throws Exception + public void endVisitSequence(final Sequence target) { // No-op. } @Override - public void beginVisitMedia(final Media target) throws Exception + public void beginVisitMedia(final Media target) { // No-op. } @Override - public void endVisitMedia(final Media target) throws Exception + public void endVisitMedia(final Media target) { // No-op. } diff --git a/src/main/java/christophedelory/playlist/Playlist.java b/src/main/java/christophedelory/playlist/Playlist.java index bcccf1e..c0c5b31 100644 --- a/src/main/java/christophedelory/playlist/Playlist.java +++ b/src/main/java/christophedelory/playlist/Playlist.java @@ -104,13 +104,13 @@ public void endVisitMedia(final Media target) } @Override - public void endVisitParallel(final Parallel target) throws Exception + public void endVisitParallel(final Parallel target) { endVisitTimeContainer(target); } @Override - public void endVisitSequence(final Sequence target) throws Exception + public void endVisitSequence(final Sequence target) { endVisitTimeContainer(target); diff --git a/src/main/java/christophedelory/playlist/PlaylistVisitor.java b/src/main/java/christophedelory/playlist/PlaylistVisitor.java index c59b92b..9778bb2 100644 --- a/src/main/java/christophedelory/playlist/PlaylistVisitor.java +++ b/src/main/java/christophedelory/playlist/PlaylistVisitor.java @@ -42,72 +42,56 @@ public interface PlaylistVisitor /** * Starts the visit of the specified playlist. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #endVisitPlaylist */ - void beginVisitPlaylist(final Playlist target) throws Exception; + void beginVisitPlaylist(final Playlist target); /** * Finishes the visit of the specified playlist. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #beginVisitPlaylist */ - void endVisitPlaylist(final Playlist target) throws Exception; + void endVisitPlaylist(final Playlist target); /** * Starts the visit of the specified parallel timing container. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #endVisitParallel */ - void beginVisitParallel(final Parallel target) throws Exception; + void beginVisitParallel(final Parallel target); /** * Finishes the visit of the specified parallel timing container. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #beginVisitParallel */ - void endVisitParallel(final Parallel target) throws Exception; + void endVisitParallel(final Parallel target); /** * Starts the visit of the specified sequence. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #endVisitSequence */ - void beginVisitSequence(final Sequence target) throws Exception; + void beginVisitSequence(final Sequence target); /** * Finishes the visit of the specified sequence. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #beginVisitSequence */ - void endVisitSequence(final Sequence target) throws Exception; + void endVisitSequence(final Sequence target); /** * Starts the visit of the specified media. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #endVisitMedia */ - void beginVisitMedia(final Media target) throws Exception; + void beginVisitMedia(final Media target); /** * Finishes the visit of the specified media. * @param target the element being visited. Shall not be null. - * @throws NullPointerException if target is null. - * @throws Exception if any error occurs during the visit. * @see #beginVisitMedia */ - void endVisitMedia(final Media target) throws Exception; + void endVisitMedia(final Media target); } diff --git a/src/main/java/christophedelory/playlist/SpecificPlaylistProvider.java b/src/main/java/christophedelory/playlist/SpecificPlaylistProvider.java index ac2ca33..350fa25 100644 --- a/src/main/java/christophedelory/playlist/SpecificPlaylistProvider.java +++ b/src/main/java/christophedelory/playlist/SpecificPlaylistProvider.java @@ -76,7 +76,7 @@ public interface SpecificPlaylistProvider * @throws NullPointerException if in is null. * @throws NullPointerException if logger is null. * @throws Exception if any error occurs during the unmarshalling process. - * @see #readFrom(final InputStream in, final String encoding) + * @see #readFrom(InputStream, String) * @see SpecificPlaylistFactory#readFrom * @see SpecificPlaylist#writeTo */ diff --git a/src/main/java/christophedelory/playlist/asx/AsxProvider.java b/src/main/java/christophedelory/playlist/asx/AsxProvider.java index 83766e2..194f431 100644 --- a/src/main/java/christophedelory/playlist/asx/AsxProvider.java +++ b/src/main/java/christophedelory/playlist/asx/AsxProvider.java @@ -224,11 +224,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the specified generic playlist component, and all its childs if any, to the input ASX elements container. * @param container the parent ASX element. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if container is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final AsxElementContainer container, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final AsxElementContainer container, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/asx/Duration.java b/src/main/java/christophedelory/playlist/asx/Duration.java index 54b1d43..ed0f1da 100644 --- a/src/main/java/christophedelory/playlist/asx/Duration.java +++ b/src/main/java/christophedelory/playlist/asx/Duration.java @@ -25,6 +25,8 @@ package christophedelory.playlist.asx; import christophedelory.lang.StringUtils; +import com.google.common.base.Splitter; +import java.util.List; /** * Defines the length of time the stream must be rendered. @@ -115,35 +117,35 @@ public String getValueString() */ public void setValueString(final String value) { - final String[] array = value.trim().split(":"); // Throws NullPointerException if value is null. Should not throw PatternSyntaxException. + final List array = Splitter.on(':').splitToList(value.trim()); // Throws NullPointerException if value is null. Should not throw PatternSyntaxException. - if (array.length != 3) + if (array.size() != 3) { throw new IllegalArgumentException("Invalid duration format " + value); } - final long hours = Long.parseLong(array[0]); // May throw NumberFormatException. + final long hours = Long.parseLong(array.get(0)); // May throw NumberFormatException. if (hours < 0L) { throw new IllegalArgumentException("Negative hours"); } - final long minutes = Long.parseLong(array[1]); // May throw NumberFormatException. + final long minutes = Long.parseLong(array.get(1)); // May throw NumberFormatException. if ((minutes < 0L) || (minutes > 59L)) { throw new IllegalArgumentException("Invalid minutes"); } - final String[] subArray = array[2].split("\\."); // Should not throw PatternSyntaxException. + final List subArray = Splitter.on('.').splitToList(array.get(2)); // Should not throw PatternSyntaxException. - if (subArray.length > 2) + if (subArray.size() > 2) { throw new IllegalArgumentException("Invalid duration format " + value); } - final long seconds = Long.parseLong(subArray[0]); // May throw NumberFormatException. + final long seconds = Long.parseLong(subArray.get(0)); // May throw NumberFormatException. if ((seconds < 0L) || (seconds > 59L)) { @@ -152,9 +154,9 @@ public void setValueString(final String value) long millis = 0L; - if (subArray.length > 1) + if (subArray.size() > 1) { - final StringBuilder sb = new StringBuilder(subArray[1]); + final StringBuilder sb = new StringBuilder(subArray.get(1)); switch (sb.length()) { diff --git a/src/main/java/christophedelory/playlist/asx/Entry.java b/src/main/java/christophedelory/playlist/asx/Entry.java index ba2bc09..26dbd22 100644 --- a/src/main/java/christophedelory/playlist/asx/Entry.java +++ b/src/main/java/christophedelory/playlist/asx/Entry.java @@ -122,7 +122,7 @@ public void setClientSkipString(final String clientSkip) { final String skip = StringUtils.normalize(clientSkip); - _clientSkip = !("NO".equalsIgnoreCase(skip)); + _clientSkip = ! "NO".equalsIgnoreCase(skip); } /** diff --git a/src/main/java/christophedelory/playlist/atom/AtomPlaylist.java b/src/main/java/christophedelory/playlist/atom/AtomPlaylist.java index c444a5e..a250039 100644 --- a/src/main/java/christophedelory/playlist/atom/AtomPlaylist.java +++ b/src/main/java/christophedelory/playlist/atom/AtomPlaylist.java @@ -24,17 +24,17 @@ */ package christophedelory.playlist.atom; -import java.io.OutputStream; -import java.io.StringWriter; - import christophedelory.atom.Entry; import christophedelory.atom.Feed; import christophedelory.atom.Link; +import christophedelory.content.Content; import christophedelory.playlist.Media; import christophedelory.playlist.Playlist; import christophedelory.playlist.SpecificPlaylist; import christophedelory.playlist.SpecificPlaylistProvider; import christophedelory.xml.XmlSerializer; +import java.io.OutputStream; +import java.io.StringWriter; /** * An Atom {@link Feed} document wrapper. @@ -100,7 +100,7 @@ public Playlist toPlaylist() if ((link.getHref() != null) && "enclosure".equals(link.getRel())) { final Media media = new Media(); // NOPMD Avoid instantiating new objects inside loops - final christophedelory.content.Content content = new christophedelory.content.Content(link.getHref()); // NOPMD Avoid instantiating new objects inside loops + final Content content = new Content(link.getHref()); // NOPMD Avoid instantiating new objects inside loops content.setType(link.getType()); if (link.getLength() != null) diff --git a/src/main/java/christophedelory/playlist/b4s/B4sProvider.java b/src/main/java/christophedelory/playlist/b4s/B4sProvider.java index 09c057d..87a7bd3 100644 --- a/src/main/java/christophedelory/playlist/b4s/B4sProvider.java +++ b/src/main/java/christophedelory/playlist/b4s/B4sProvider.java @@ -121,11 +121,8 @@ public SpecificPlaylist toSpecificPlaylist(final christophedelory.playlist.Playl * Adds the specified generic playlist component, and all its childs if any, to the input playlist. * @param playlist the parent playlist. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if playlist is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final Playlist playlist, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final Playlist playlist, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/hypetape/HypetapeProvider.java b/src/main/java/christophedelory/playlist/hypetape/HypetapeProvider.java index 50ac55b..13ad3a8 100644 --- a/src/main/java/christophedelory/playlist/hypetape/HypetapeProvider.java +++ b/src/main/java/christophedelory/playlist/hypetape/HypetapeProvider.java @@ -118,11 +118,8 @@ public SpecificPlaylist toSpecificPlaylist(final christophedelory.playlist.Playl * Adds the specified generic playlist component, and all its childs if any, to the input track list. * @param playlist the parent playlist. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if playlist is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final Playlist playlist, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final Playlist playlist, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/kpl/Info.java b/src/main/java/christophedelory/playlist/kpl/Info.java index 157e966..dfbd04a 100644 --- a/src/main/java/christophedelory/playlist/kpl/Info.java +++ b/src/main/java/christophedelory/playlist/kpl/Info.java @@ -46,7 +46,7 @@ public class Info /** * The internal date format. */ - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * The creation day. @@ -90,10 +90,7 @@ public String getCreationDayString() if (_creation_day != null) { - synchronized(DATE_FORMAT) - { - ret = DATE_FORMAT.format(_creation_day); // Should not throw NullPointerException because of _creation_day. - } + ret = dateFormat.get().format(_creation_day); // Should not throw NullPointerException because of _creation_day. } return ret; @@ -116,10 +113,7 @@ public void setCreationDayString(final String creationDay) throws ParseException } else { - synchronized(DATE_FORMAT) - { - _creation_day = DATE_FORMAT.parse(day); // May throw ParseException. - } + _creation_day = dateFormat.get().parse(day); // May throw ParseException. } } @@ -157,10 +151,7 @@ public String getModifiedDayString() if (_modified_day != null) { - synchronized(DATE_FORMAT) - { - ret = DATE_FORMAT.format(_modified_day); // Should not throw NullPointerException because of _modified_day. - } + ret = dateFormat.get().format(_modified_day); // Should not throw NullPointerException because of _modified_day. } return ret; @@ -183,10 +174,7 @@ public void setModifiedDayString(final String modifiedDay) throws ParseException } else { - synchronized(DATE_FORMAT) - { - _modified_day = DATE_FORMAT.parse(day); // May throw ParseException. - } + _modified_day = dateFormat.get().parse(day); // May throw ParseException. } } diff --git a/src/main/java/christophedelory/playlist/kpl/KplProvider.java b/src/main/java/christophedelory/playlist/kpl/KplProvider.java index c63304d..5e46dee 100644 --- a/src/main/java/christophedelory/playlist/kpl/KplProvider.java +++ b/src/main/java/christophedelory/playlist/kpl/KplProvider.java @@ -197,11 +197,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the specified generic playlist component, and all its childs if any, to the input list. * @param entries the parent list of entries. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if entries is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final List entries, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final List entries, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/m3u/M3UProvider.java b/src/main/java/christophedelory/playlist/m3u/M3UProvider.java index 75b6dd9..3062552 100644 --- a/src/main/java/christophedelory/playlist/m3u/M3UProvider.java +++ b/src/main/java/christophedelory/playlist/m3u/M3UProvider.java @@ -198,11 +198,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the resources referenced in the specified generic playlist component to the input list. * @param resources the resulting list of resources. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if resources is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final List resources, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final List resources, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/mpcpl/MPCPLProvider.java b/src/main/java/christophedelory/playlist/mpcpl/MPCPLProvider.java index e738e1c..0a7aac6 100644 --- a/src/main/java/christophedelory/playlist/mpcpl/MPCPLProvider.java +++ b/src/main/java/christophedelory/playlist/mpcpl/MPCPLProvider.java @@ -194,11 +194,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the resources referenced in the specified generic playlist component to the input list. * @param resources the resulting list of resources. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if resources is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final List resources, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final List resources, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/pla/PLA.java b/src/main/java/christophedelory/playlist/pla/PLA.java index 8178510..36aac67 100644 --- a/src/main/java/christophedelory/playlist/pla/PLA.java +++ b/src/main/java/christophedelory/playlist/pla/PLA.java @@ -25,6 +25,7 @@ package christophedelory.playlist.pla; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.ArrayList; import java.util.List; @@ -86,7 +87,7 @@ public void writeTo(final OutputStream out, final String encoding) throws Except array[17] = 'A'; final int nbSongs = _filenames.size(); - array[3] = (byte)((nbSongs & 0x000000ff) >> 0); + array[3] = (byte)((nbSongs & 0x000000ff)); array[2] = (byte)((nbSongs & 0x0000ff00) >> 8); array[1] = (byte)((nbSongs & 0x00ff0000) >> 16); array[0] = (byte)((nbSongs & 0xff000000) >> 24); @@ -112,10 +113,10 @@ else if (antislashIndex > slashIndex) // And thus is greater or equal to 0. // File index is one-based. fileIndex++; - array[1] = (byte)((fileIndex & 0x000000ff) >> 0); + array[1] = (byte)((fileIndex & 0x000000ff)); array[0] = (byte)((fileIndex & 0x0000ff00) >> 8); - final byte[] tmp = filename.getBytes("UTF-16BE"); // Shall not throw UnsupportedEncodingException. + final byte[] tmp = filename.getBytes(StandardCharsets.UTF_16BE); // Shall not throw UnsupportedEncodingException. System.arraycopy(tmp, 0, array, 2, tmp.length); // May throw IndexOutOfBoundsException. Shall not throw ArrayStoreException, NullPointerException. out.write(array); // May throw IOException. diff --git a/src/main/java/christophedelory/playlist/pla/PLAProvider.java b/src/main/java/christophedelory/playlist/pla/PLAProvider.java index 95c9a52..a788cf5 100644 --- a/src/main/java/christophedelory/playlist/pla/PLAProvider.java +++ b/src/main/java/christophedelory/playlist/pla/PLAProvider.java @@ -25,6 +25,7 @@ package christophedelory.playlist.pla; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import christophedelory.playlist.*; @@ -90,7 +91,7 @@ public SpecificPlaylist readFrom(final InputStream in, final String encoding, fi // First frame is a header starting with a 32-bit big-endian unsigned integer specifying the number of songs in the playlist. // Immediately after this there is an ASCII string "iriver UMS PLA", and that's all for the header frame. - final String magic = new String(array, 4, 14, "US-ASCII"); // Shall not throw UnsupportedEncodingException, IndexOutOfBoundsException. + final String magic = new String(array, 4, 14, StandardCharsets.US_ASCII); // Shall not throw UnsupportedEncodingException, IndexOutOfBoundsException. if (!"iriver UMS PLA".equals(magic)) { @@ -100,7 +101,7 @@ public SpecificPlaylist readFrom(final InputStream in, final String encoding, fi // In addition, player's own Quick Lists have an apparently superfluous extra string "Quick List" starting from 0x20 //magic = new String(array, 32, 10); // May equal "Quick List". - final int nbSongs = (((int) array[3] & 0x0ff) << 0) | + final int nbSongs = (((int) array[3] & 0x0ff)) | (((int) array[2] & 0x0ff) << 8) | (((int) array[1] & 0x0ff) << 16) | (((int) array[0] & 0x0ff) << 24); @@ -125,7 +126,7 @@ public SpecificPlaylist readFrom(final InputStream in, final String encoding, fi // As the filesystem type is VFAT, it is encoded as big-endian UTF-16 without a byte order mark. // I have not tried whether the player recognizes wider than two-byte characters. // Also, I have used only absolute paths, I don't know if relative paths would work. - final String songFilename = new String(array, 2, 510, "UTF-16BE"); // Shall not throw UnsupportedEncodingException, IndexOutOfBoundsException. NOPMD Avoid instantiating new objects inside loops + final String songFilename = new String(array, 2, 510, StandardCharsets.UTF_16BE); // Shall not throw UnsupportedEncodingException, IndexOutOfBoundsException. NOPMD Avoid instantiating new objects inside loops // The index and filename are everything there is in a single song frame. // Note that the filename must fit into one 512-byte frame. @@ -151,11 +152,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the song file names referenced in the specified generic playlist component to the input list. * @param filenames the resulting list of file names. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if filenames is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final List filenames, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final List filenames, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/plist/PlistProvider.java b/src/main/java/christophedelory/playlist/plist/PlistProvider.java index ee1be98..ba56886 100644 --- a/src/main/java/christophedelory/playlist/plist/PlistProvider.java +++ b/src/main/java/christophedelory/playlist/plist/PlistProvider.java @@ -150,13 +150,9 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * @param tracks the list of tracks. Shall not be null. * @param playlist the playlist. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if tracks is null. - * @throws NullPointerException if playlist is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") - private void addToPlaylist(final Dict tracks, final Array playlist, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final Dict tracks, final Array playlist, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/plp/PLPProvider.java b/src/main/java/christophedelory/playlist/plp/PLPProvider.java index c2b2058..b375db7 100644 --- a/src/main/java/christophedelory/playlist/plp/PLPProvider.java +++ b/src/main/java/christophedelory/playlist/plp/PLPProvider.java @@ -176,11 +176,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the song file names referenced in the specified generic playlist component to the input list. * @param filenames the resulting list of file names. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if filenames is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final List filenames, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final List filenames, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/pls/PLSProvider.java b/src/main/java/christophedelory/playlist/pls/PLSProvider.java index c412890..d0fd498 100644 --- a/src/main/java/christophedelory/playlist/pls/PLSProvider.java +++ b/src/main/java/christophedelory/playlist/pls/PLSProvider.java @@ -311,11 +311,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the resources referenced in the specified generic playlist component to the input list. * @param resources the resulting list of resources. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if resources is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final List resources, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final List resources, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/rmp/Package.java b/src/main/java/christophedelory/playlist/rmp/Package.java index 64afad5..79a2074 100644 --- a/src/main/java/christophedelory/playlist/rmp/Package.java +++ b/src/main/java/christophedelory/playlist/rmp/Package.java @@ -56,7 +56,7 @@ public class Package implements SpecificPlaylist /** * The internal date and time format. */ - private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal datetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("MM/dd/yyyy HH:mm", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * The provider of this specific playlist. @@ -266,10 +266,7 @@ public String getExpirationDateString() if (_expirationDate != null) { - synchronized(DATETIME_FORMAT) - { - ret = DATETIME_FORMAT.format(_expirationDate); // Should not throw NullPointerException because of _expirationDate. - } + ret = datetimeFormat.get().format(_expirationDate); // Should not throw NullPointerException because of _expirationDate. } return ret; @@ -285,10 +282,7 @@ public String getExpirationDateString() */ public void setExpirationDateString(final String expirationDate) throws ParseException { - synchronized(DATETIME_FORMAT) - { - _expirationDate = DATETIME_FORMAT.parse(expirationDate); // May throw ParseException. Throws NullPointerException if expirationDate is null. - } + _expirationDate = datetimeFormat.get().parse(expirationDate); // May throw ParseException. Throws NullPointerException if expirationDate is null. } /** diff --git a/src/main/java/christophedelory/playlist/rmp/RmpProvider.java b/src/main/java/christophedelory/playlist/rmp/RmpProvider.java index f59de03..f39d04c 100644 --- a/src/main/java/christophedelory/playlist/rmp/RmpProvider.java +++ b/src/main/java/christophedelory/playlist/rmp/RmpProvider.java @@ -135,11 +135,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the specified generic playlist component, and all its childs if any, to the input track list. * @param trackList the parent track list. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if trackList is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final Tracklist trackList, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final Tracklist trackList, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/smil/AbstractSmilElement.java b/src/main/java/christophedelory/playlist/smil/AbstractSmilElement.java index dac951f..fd89006 100644 --- a/src/main/java/christophedelory/playlist/smil/AbstractSmilElement.java +++ b/src/main/java/christophedelory/playlist/smil/AbstractSmilElement.java @@ -25,6 +25,8 @@ package christophedelory.playlist.smil; import christophedelory.lang.StringUtils; +import com.google.common.base.Splitter; +import java.util.List; /** * The media object elements. @@ -415,43 +417,43 @@ else if (INDEFINITE.equalsIgnoreCase(str)) long minutes = 0L; long seconds = 0L; long millis = 0L; - final String[] array = str.split(":"); // Should not throw PatternSyntaxException. + final List array = Splitter.on(':').splitToList(str); // Should not throw PatternSyntaxException. - switch (array.length) // NOPMD A high ratio of statements to labels in a switch statement. Consider refactoring + switch (array.size()) // NOPMD A high ratio of statements to labels in a switch statement. Consider refactoring { case 3: // Full-clock-value ::= Hours ":" Minutes ":" Seconds ("." Fraction)? { - hours = Long.parseLong(array[0]); // May throw NumberFormatException. + hours = Long.parseLong(array.get(0)); // May throw NumberFormatException. if (hours < 0L) { throw new IllegalArgumentException("Negative hours"); } - minutes = Long.parseLong(array[1]); // May throw NumberFormatException. + minutes = Long.parseLong(array.get(1)); // May throw NumberFormatException. if ((minutes < 0L) || (minutes > 59L)) { throw new IllegalArgumentException("Invalid minutes"); } - final String[] subArray = array[2].split("\\."); // Should not throw PatternSyntaxException. + final List subArray = Splitter.on('.').splitToList(array.get(2)); // Should not throw PatternSyntaxException. - if (subArray.length > 2) + if (subArray.size() > 2) { throw new IllegalArgumentException("Invalid duration format " + str); } - seconds = Long.parseLong(subArray[0]); // May throw NumberFormatException. + seconds = Long.parseLong(subArray.get(0)); // May throw NumberFormatException. if ((seconds < 0L) || (seconds > 59L)) { throw new IllegalArgumentException("Invalid seconds"); } - if (subArray.length > 1) + if (subArray.size() > 1) { - final StringBuilder sb = new StringBuilder(subArray[1]); + final StringBuilder sb = new StringBuilder(subArray.get(1)); switch (sb.length()) { @@ -481,30 +483,30 @@ else if (INDEFINITE.equalsIgnoreCase(str)) case 2: // Partial-clock-value ::= Minutes ":" Seconds ("." Fraction)? { - minutes = Long.parseLong(array[0]); // May throw NumberFormatException. + minutes = Long.parseLong(array.get(0)); // May throw NumberFormatException. if ((minutes < 0L) || (minutes > 59L)) { throw new IllegalArgumentException("Invalid minutes"); } - final String[] subArray = array[1].split("\\."); // Should not throw PatternSyntaxException. + final List subArray = Splitter.on('.').splitToList(array.get(1)); // Should not throw PatternSyntaxException. - if (subArray.length > 2) + if (subArray.size() > 2) { throw new IllegalArgumentException("Invalid duration format " + str); } - seconds = Long.parseLong(subArray[0]); // May throw NumberFormatException. + seconds = Long.parseLong(subArray.get(0)); // May throw NumberFormatException. if ((seconds < 0L) || (seconds > 59L)) { throw new IllegalArgumentException("Invalid seconds"); } - if (subArray.length > 1) + if (subArray.size() > 1) { - final StringBuilder sb = new StringBuilder(subArray[1]); + final StringBuilder sb = new StringBuilder(subArray.get(1)); switch (sb.length()) { @@ -534,7 +536,7 @@ else if (INDEFINITE.equalsIgnoreCase(str)) case 1: // Timecount-value ::= Timecount ("." Fraction)? (Metric)? { - String input = array[0].toLowerCase(); // Default value. + String input = array.get(0).toLowerCase(); // Default value. float multiplier = 1000f; // Default value. if (input.endsWith("h")) diff --git a/src/main/java/christophedelory/playlist/smil/Head.java b/src/main/java/christophedelory/playlist/smil/Head.java index e9dd8a5..ed15ce4 100644 --- a/src/main/java/christophedelory/playlist/smil/Head.java +++ b/src/main/java/christophedelory/playlist/smil/Head.java @@ -25,6 +25,7 @@ package christophedelory.playlist.smil; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; /** @@ -115,7 +116,7 @@ public Meta findMetaByName(final String name) public boolean removeMetaByName(final String name) { boolean ret = false; - final java.util.Iterator iter = _metas.iterator(); + final Iterator iter = _metas.iterator(); while (iter.hasNext()) { diff --git a/src/main/java/christophedelory/playlist/smil/ParamGroup.java b/src/main/java/christophedelory/playlist/smil/ParamGroup.java index 82c8f9c..5b32c15 100644 --- a/src/main/java/christophedelory/playlist/smil/ParamGroup.java +++ b/src/main/java/christophedelory/playlist/smil/ParamGroup.java @@ -55,7 +55,7 @@ public class ParamGroup extends Core */ public boolean isSkipContent() { - return (_skipContent == null) ? false : _skipContent.booleanValue(); + return _skipContent != null && _skipContent.booleanValue(); } /** diff --git a/src/main/java/christophedelory/playlist/smil/Region.java b/src/main/java/christophedelory/playlist/smil/Region.java index 787f4a3..b51a03f 100644 --- a/src/main/java/christophedelory/playlist/smil/Region.java +++ b/src/main/java/christophedelory/playlist/smil/Region.java @@ -288,7 +288,7 @@ public void setWidth(final int width) */ public boolean isSkipContent() { - return (_skipContent == null) ? false : _skipContent.booleanValue(); + return _skipContent != null && _skipContent.booleanValue(); } /** diff --git a/src/main/java/christophedelory/playlist/smil/RegistrationPoint.java b/src/main/java/christophedelory/playlist/smil/RegistrationPoint.java index 84b6db8..3e50b4e 100644 --- a/src/main/java/christophedelory/playlist/smil/RegistrationPoint.java +++ b/src/main/java/christophedelory/playlist/smil/RegistrationPoint.java @@ -82,7 +82,7 @@ public void setRegAlign(final String regAlign) */ public boolean isSkipContent() { - return (_skipContent == null) ? false : _skipContent.booleanValue(); + return _skipContent != null && _skipContent.booleanValue(); } /** diff --git a/src/main/java/christophedelory/playlist/smil/RootLayout.java b/src/main/java/christophedelory/playlist/smil/RootLayout.java index 8a4eb18..bb06829 100644 --- a/src/main/java/christophedelory/playlist/smil/RootLayout.java +++ b/src/main/java/christophedelory/playlist/smil/RootLayout.java @@ -197,7 +197,7 @@ public void setWidth(final int width) */ public boolean isSkipContent() { - return (_skipContent == null) ? false : _skipContent.booleanValue(); + return _skipContent != null && _skipContent.booleanValue(); } /** diff --git a/src/main/java/christophedelory/playlist/smil/SmilProvider.java b/src/main/java/christophedelory/playlist/smil/SmilProvider.java index 168f9ed..7b43149 100644 --- a/src/main/java/christophedelory/playlist/smil/SmilProvider.java +++ b/src/main/java/christophedelory/playlist/smil/SmilProvider.java @@ -107,7 +107,7 @@ public SpecificPlaylist readFrom(final InputStream in, final String encoding, fi } @Override - public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Exception + public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) { final Smil ret = new Smil(); ret.setProvider(this); diff --git a/src/main/java/christophedelory/playlist/wpl/Head.java b/src/main/java/christophedelory/playlist/wpl/Head.java index f8adeee..ee40c47 100644 --- a/src/main/java/christophedelory/playlist/wpl/Head.java +++ b/src/main/java/christophedelory/playlist/wpl/Head.java @@ -24,11 +24,11 @@ */ package christophedelory.playlist.wpl; +import christophedelory.lang.StringUtils; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -import christophedelory.lang.StringUtils; - /** * Contains metadata that applies to the entire playlist. * Typically the head element contains a title element and one or more meta elements that define global characteristics of the playlist. @@ -178,7 +178,7 @@ public Meta findMetaByName(final String name) public boolean removeMetaByName(final String name) { boolean ret = false; - final java.util.Iterator iter = _metas.iterator(); + final Iterator iter = _metas.iterator(); while (iter.hasNext()) { diff --git a/src/main/java/christophedelory/playlist/wpl/WplProvider.java b/src/main/java/christophedelory/playlist/wpl/WplProvider.java index 3ad5a32..3a8e43d 100644 --- a/src/main/java/christophedelory/playlist/wpl/WplProvider.java +++ b/src/main/java/christophedelory/playlist/wpl/WplProvider.java @@ -129,11 +129,8 @@ public SpecificPlaylist toSpecificPlaylist(final Playlist playlist) throws Excep * Adds the specified generic playlist component, and all its childs if any, to the input sequence. * @param wplSeq the parent sequence. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if wplSeq is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final Seq wplSeq, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final Seq wplSeq, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/playlist/xspf/Track.java b/src/main/java/christophedelory/playlist/xspf/Track.java index 9b4b729..ba98a2b 100644 --- a/src/main/java/christophedelory/playlist/xspf/Track.java +++ b/src/main/java/christophedelory/playlist/xspf/Track.java @@ -390,7 +390,7 @@ public void addExtension(final Object extension) throw new IllegalArgumentException("No application attribute"); } - if (!"application".equals(attr.getLocalName())) + if (!attr.getLocalName().equals("application")) { throw new IllegalArgumentException("Unknown attribute"); } diff --git a/src/main/java/christophedelory/playlist/xspf/XspfProvider.java b/src/main/java/christophedelory/playlist/xspf/XspfProvider.java index b51ddbf..316b58b 100644 --- a/src/main/java/christophedelory/playlist/xspf/XspfProvider.java +++ b/src/main/java/christophedelory/playlist/xspf/XspfProvider.java @@ -120,11 +120,8 @@ public SpecificPlaylist toSpecificPlaylist(final christophedelory.playlist.Playl * Adds the specified generic playlist component, and all its childs if any, to the input track list. * @param playlist the parent playlist. Shall not be null. * @param component the generic playlist component to handle. Shall not be null. - * @throws NullPointerException if playlist is null. - * @throws NullPointerException if component is null. - * @throws Exception if this service provider is unable to represent the input playlist. */ - private void addToPlaylist(final Playlist playlist, final AbstractPlaylistComponent component) throws Exception + private void addToPlaylist(final Playlist playlist, final AbstractPlaylistComponent component) { if (component instanceof Sequence) { diff --git a/src/main/java/christophedelory/plist/Date.java b/src/main/java/christophedelory/plist/Date.java index 231c271..e8fc5ec 100644 --- a/src/main/java/christophedelory/plist/Date.java +++ b/src/main/java/christophedelory/plist/Date.java @@ -42,7 +42,7 @@ public class Date extends PlistObject /** * The internal date and time format. */ - private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal datetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * The date. @@ -89,10 +89,7 @@ public Date(final java.util.Date value) */ public java.lang.String getValueString() { - synchronized(DATETIME_FORMAT) - { - return DATETIME_FORMAT.format(_value); // Throws NullPointerException if _value is null. - } + return datetimeFormat.get().format(_value); // Throws NullPointerException if _value is null. } /** @@ -105,10 +102,7 @@ public java.lang.String getValueString() */ public void setValueString(final java.lang.String value) throws ParseException { - synchronized(DATETIME_FORMAT) - { - _value = DATETIME_FORMAT.parse(value); // May throw ParseException. Throws NullPointerException if value is null. - } + _value = datetimeFormat.get().parse(value); // May throw ParseException. Throws NullPointerException if value is null. } /** diff --git a/src/main/java/christophedelory/rss/RFC822.java b/src/main/java/christophedelory/rss/RFC822.java index f6167f6..2e82d31 100644 --- a/src/main/java/christophedelory/rss/RFC822.java +++ b/src/main/java/christophedelory/rss/RFC822.java @@ -17,29 +17,29 @@ final class RFC822 /** * RFC822 date and time format, full version. */ - private static final DateFormat FULL_RFC822_DATETIME_FORMAT = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal fullRfc822DatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * RFC822 date and time format, full version, without seconds. */ - private static final DateFormat FULL_RFC822_DATETIME_FORMAT_2 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm Z", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal fullRfc822DatetimeFormat2 = ThreadLocal.withInitial(() -> new SimpleDateFormat("EEE, d MMM yyyy HH:mm Z", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * RFC822 date and time format, compact version. */ - private static final DateFormat COMPACT_RFC822_DATETIME_FORMAT = new SimpleDateFormat("d MMM yyyy HH:mm:ss Z", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal compactRfc822DatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("d MMM yyyy HH:mm:ss Z", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * RFC822 date and time format, compact version, without seconds. */ - private static final DateFormat COMPACT_RFC822_DATETIME_FORMAT_2 = new SimpleDateFormat("d MMM yyyy HH:mm Z", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + private static final ThreadLocal compactRfc822DatetimeFormat2 = ThreadLocal.withInitial(() -> new SimpleDateFormat("d MMM yyyy HH:mm Z", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * The ISO8601 {@link Date} formatter for date-time without time zone. * The {@link java.util.TimeZone} used here is the default local time zone. * The input {@link Date} is a GMT date and time. */ - public static final DateFormat ISO8601_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US); // Should not throw NullPointerException, IllegalArgumentException. + public static final ThreadLocal iso8601DatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US)); // Should not throw NullPointerException, IllegalArgumentException. /** * Returns a RFC822 date and time string representation of the specified date. @@ -49,10 +49,7 @@ final class RFC822 */ public static String toString(final Date date) { - synchronized(FULL_RFC822_DATETIME_FORMAT) - { - return FULL_RFC822_DATETIME_FORMAT.format(date); // Throws NullPointerException if date is null. - } + return fullRfc822DatetimeFormat.get().format(date); // Throws NullPointerException if date is null. } /** @@ -63,70 +60,27 @@ public static String toString(final Date date) */ public static Date valueOf(final String dateString) { - Date ret = null; + DateFormat[] formatsToTry = { + fullRfc822DatetimeFormat.get(), + fullRfc822DatetimeFormat2.get(), + compactRfc822DatetimeFormat.get(), + compactRfc822DatetimeFormat2.get() + }; - synchronized(FULL_RFC822_DATETIME_FORMAT) + for(DateFormat dateFormat : formatsToTry) { try { - ret = FULL_RFC822_DATETIME_FORMAT.parse(dateString); // May throw ParseException. Throws NullPointerException if dateString is null. - } - catch (ParseException e) - { - // Continue and try next format. - ret = null; - } - } - - if (ret == null) - { - synchronized(FULL_RFC822_DATETIME_FORMAT_2) - { - try - { - ret = FULL_RFC822_DATETIME_FORMAT_2.parse(dateString); // May throw ParseException. - } - catch (ParseException e) - { - // Continue and try next format. - ret = null; - } + Date ret = dateFormat.parse(dateString); // May throw ParseException. Throws NullPointerException if dateString is null. + if (ret != null) + return ret; } - } - - if (ret == null) - { - synchronized(COMPACT_RFC822_DATETIME_FORMAT) + catch (ParseException ignore) { - try - { - ret = COMPACT_RFC822_DATETIME_FORMAT.parse(dateString); // May throw ParseException. - } - catch (ParseException e) - { - // Continue and try next format. - ret = null; - } + // Try next format } } - - if (ret == null) - { - synchronized(COMPACT_RFC822_DATETIME_FORMAT_2) - { - try - { - ret = COMPACT_RFC822_DATETIME_FORMAT_2.parse(dateString); // May throw ParseException. - } - catch (ParseException e) - { - // Continue and try next format. - ret = null; - } - } - } - - return ret; + return null; } /** diff --git a/src/main/java/christophedelory/rss/media/BaseMedia.java b/src/main/java/christophedelory/rss/media/BaseMedia.java index 8eec746..0189260 100644 --- a/src/main/java/christophedelory/rss/media/BaseMedia.java +++ b/src/main/java/christophedelory/rss/media/BaseMedia.java @@ -224,7 +224,7 @@ public void setMediaDescription(final Description mediaDescription) */ public boolean isMediaAdult() { - return (_mediaAdult == null) ? false : _mediaAdult.booleanValue(); + return _mediaAdult != null && _mediaAdult.booleanValue(); } /** diff --git a/src/main/java/christophedelory/rss/media/Content.java b/src/main/java/christophedelory/rss/media/Content.java index e198f53..6bf450c 100644 --- a/src/main/java/christophedelory/rss/media/Content.java +++ b/src/main/java/christophedelory/rss/media/Content.java @@ -534,7 +534,8 @@ public void setLang(final String lang) */ public boolean isDefault() { - return (_isDefault == null) ? false /*FIXME TBC*/ : _isDefault.booleanValue(); + /*FIXME TBC*/ + return _isDefault != null && _isDefault.booleanValue(); } /** diff --git a/src/main/java/christophedelory/rss/media/Copyright.java b/src/main/java/christophedelory/rss/media/Copyright.java index 1ddcac7..7caec76 100644 --- a/src/main/java/christophedelory/rss/media/Copyright.java +++ b/src/main/java/christophedelory/rss/media/Copyright.java @@ -127,10 +127,11 @@ public String getValue() } /** - * + *See {@link #getValue}. + * @param value the copyright information. Shall not be null. * @throws NullPointerException if value is null. - * @see #getValue + * */ public void setValue(final String value) { diff --git a/src/main/java/christophedelory/xml/XmlSerializer.java b/src/main/java/christophedelory/xml/XmlSerializer.java index 5c5fa64..943dff3 100644 --- a/src/main/java/christophedelory/xml/XmlSerializer.java +++ b/src/main/java/christophedelory/xml/XmlSerializer.java @@ -24,23 +24,25 @@ */ package christophedelory.xml; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; import java.io.Reader; import java.io.Writer; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Hashtable; - -import org.xml.sax.InputSource; - import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.MappingException; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; +import org.xml.sax.InputSource; /** * A collection of utilities when manipulating the Castor framework. @@ -53,7 +55,7 @@ public final class XmlSerializer /** * The list of mappings already built. */ - private static Hashtable _mappings = new Hashtable(); + private static final Hashtable _mappings = new Hashtable(); /** * Retrieves the XML serializer instance associated to the specified package name. @@ -213,7 +215,7 @@ public Object unmarshal(final Reader reader) throws Exception */ public void marshal(final Object o, final String fileName, final boolean asDocument) throws Exception { - final FileWriter out = new FileWriter(fileName, false); // May throw IOException. + final Writer out = Files.newBufferedWriter(Paths.get(fileName), UTF_8); // May throw IOException. marshal(o, out, asDocument); // May throw MappingException, MarshalException, ValidationException. out.flush(); // May throw IOException. out.close(); // May throw IOException. @@ -236,7 +238,7 @@ public void marshal(final Object o, final String fileName, final boolean asDocum */ public void marshal(final Object o, final File file, final boolean asDocument) throws Exception { - final FileWriter out = new FileWriter(file, false); // May throw IOException. + final Writer out = Files.newBufferedWriter(file.toPath(), UTF_8); // May throw IOException. marshal(o, out, asDocument); // May throw MappingException, MarshalException, ValidationException. out.flush(); // May throw IOException. out.close(); // May throw IOException. diff --git a/src/test/java/christophedelory/TranscodeTests.java b/src/test/java/christophedelory/TranscodeTests.java index 20aed3d..7103c62 100644 --- a/src/test/java/christophedelory/TranscodeTests.java +++ b/src/test/java/christophedelory/TranscodeTests.java @@ -41,10 +41,23 @@ public void transcodePlaylist(String type) throws IOException transcode(samplePath); } catch(Exception e) { fail(String.format("Transconding of \"%s\" failed", samplePath)); + } } } + @Test + public void transcodeAtomPlaylist() throws Exception + { + List samples = getSamplePaths().stream() + .filter(sample -> sample.toString().endsWith("test02.atom")) + .collect(Collectors.toList()); + + for(Path samplePath: samples) { + transcode(samplePath); + } + } + private void transcode(Path samplePath) throws Exception { final String[] targetPlaylistFormats = {"pla", "asx", "b4s", "wpl", "smil", "rss", "atom", "hypetape", "xspf", "rmp", "plist", "kpl", "pls", "mpcpl", "plp", "m3u"}; diff --git a/test/AddToPlaylist.sh b/test/AddToPlaylist.sh index f91f13f..7ee23ae 100644 --- a/test/AddToPlaylist.sh +++ b/test/AddToPlaylist.sh @@ -1,4 +1,4 @@ #!/bin/sh -root=`dirname $0` +root=`dirname "$0"` LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$root/lib -java -cp "$root/lizzy.jar:$root/lib/args4j.jar:$root/classes" christophedelory.lizzy.AddToPlaylist $* +java -cp "$root/lizzy.jar:$root/lib/args4j.jar:$root/classes" christophedelory.lizzy.AddToPlaylist "$*" diff --git a/test/ContentTypeInfo.sh b/test/ContentTypeInfo.sh index 452d516..296b52a 100644 --- a/test/ContentTypeInfo.sh +++ b/test/ContentTypeInfo.sh @@ -1,3 +1,3 @@ #!/bin/sh -root=`dirname $0` -java -cp "$root/lizzy.jar:$root/classes" christophedelory.lizzy.ContentTypeInfo $* +root=`dirname "$0"` +java -cp "$root/lizzy.jar:$root/classes" christophedelory.lizzy.ContentTypeInfo "$*"