]> git.basschouten.com Git - openhab-addons.git/commitdiff
[voicerss] Null annotations added on the main service class (#12190)
authorlolodomo <lg.hc@free.fr>
Thu, 3 Feb 2022 18:48:14 +0000 (19:48 +0100)
committerGitHub <noreply@github.com>
Thu, 3 Feb 2022 18:48:14 +0000 (19:48 +0100)
Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.voice.voicerss/src/main/java/org/openhab/voice/voicerss/internal/VoiceRSSTTSService.java
bundles/org.openhab.voice.voicerss/src/main/java/org/openhab/voice/voicerss/tool/CreateTTSCache.java

index 73eecbec82c40af563ade56903c931c64cb29705..ca25f7342ecef1aff005a2f1f8b862167185ac00 100644 (file)
@@ -20,6 +20,8 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.OpenHAB;
 import org.openhab.core.audio.AudioException;
 import org.openhab.core.audio.AudioFormat;
@@ -30,6 +32,7 @@ import org.openhab.core.voice.TTSService;
 import org.openhab.core.voice.Voice;
 import org.openhab.voice.voicerss.internal.cloudapi.CachedVoiceRSSCloudImpl;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Modified;
 import org.slf4j.Logger;
@@ -41,6 +44,7 @@ import org.slf4j.LoggerFactory;
  * @author Jochen Hiller - Initial contribution and API
  * @author Laurent Garnier - add support for OGG and AAC audio formats
  */
+@NonNullByDefault
 @Component(configurationPid = "org.openhab.voicerss", property = Constants.SERVICE_PID + "=org.openhab.voicerss")
 @ConfigurableService(category = "voice", label = "VoiceRSS Text-to-Speech", description_uri = "voice:voicerss")
 public class VoiceRSSTTSService implements TTSService {
@@ -66,27 +70,28 @@ public class VoiceRSSTTSService implements TTSService {
 
     private final Logger logger = LoggerFactory.getLogger(VoiceRSSTTSService.class);
 
-    private String apiKey;
+    private @Nullable String apiKey;
 
     /**
      * We need the cached implementation to allow for FixedLengthAudioStream.
      */
-    private CachedVoiceRSSCloudImpl voiceRssImpl;
+    private @Nullable CachedVoiceRSSCloudImpl voiceRssImpl;
 
     /**
      * Set of supported voices
      */
-    private Set<Voice> voices;
+    private @Nullable Set<Voice> voices;
 
     /**
      * Set of supported audio formats
      */
-    private Set<AudioFormat> audioFormats;
+    private @Nullable Set<AudioFormat> audioFormats;
 
     /**
      * DS activate, with access to ConfigAdmin
      */
-    protected void activate(Map<String, Object> config) {
+    @Activate
+    protected void activate(@Nullable Map<String, Object> config) {
         try {
             modified(config);
             voiceRssImpl = initVoiceImplementation();
@@ -100,7 +105,7 @@ public class VoiceRSSTTSService implements TTSService {
     }
 
     @Modified
-    protected void modified(Map<String, Object> config) {
+    protected void modified(@Nullable Map<String, Object> config) {
         if (config != null) {
             apiKey = config.containsKey(CONFIG_API_KEY) ? config.get(CONFIG_API_KEY).toString() : null;
         }
@@ -108,37 +113,41 @@ public class VoiceRSSTTSService implements TTSService {
 
     @Override
     public Set<Voice> getAvailableVoices() {
-        return Collections.unmodifiableSet(voices);
+        Set<Voice> localVoices = voices;
+        return localVoices == null ? Set.of() : Collections.unmodifiableSet(localVoices);
     }
 
     @Override
     public Set<AudioFormat> getSupportedFormats() {
-        return Collections.unmodifiableSet(audioFormats);
+        Set<AudioFormat> localFormats = audioFormats;
+        return localFormats == null ? Set.of() : Collections.unmodifiableSet(localFormats);
     }
 
     @Override
     public AudioStream synthesize(String text, Voice voice, AudioFormat requestedFormat) throws TTSException {
         logger.debug("Synthesize '{}' for voice '{}' in format {}", text, voice.getUID(), requestedFormat);
+        CachedVoiceRSSCloudImpl voiceRssCloud = voiceRssImpl;
+        if (voiceRssCloud == null) {
+            throw new TTSException("The service is not correctly initialized");
+        }
         // Validate known api key
-        if (apiKey == null) {
+        String key = apiKey;
+        if (key == null) {
             throw new TTSException("Missing API key, configure it first before using");
         }
-        // Validate arguments
-        if (text == null) {
-            throw new TTSException("The passed text is null");
-        }
         // trim text
         String trimmedText = text.trim();
         if (trimmedText.isEmpty()) {
             throw new TTSException("The passed text is empty");
         }
-        if (!voices.contains(voice)) {
+        Set<Voice> localVoices = voices;
+        if (localVoices == null || !localVoices.contains(voice)) {
             throw new TTSException("The passed voice is unsupported");
         }
 
         // now create the input stream for given text, locale, voice, codec and format.
         try {
-            File cacheAudioFile = voiceRssImpl.getTextToSpeechAsFile(apiKey, trimmedText,
+            File cacheAudioFile = voiceRssCloud.getTextToSpeechAsFile(key, trimmedText,
                     voice.getLocale().toLanguageTag(), voice.getLabel(), getApiAudioCodec(requestedFormat),
                     getApiAudioFormat(requestedFormat));
             return new VoiceRSSAudioStream(cacheAudioFile, requestedFormat);
@@ -153,11 +162,16 @@ public class VoiceRSSTTSService implements TTSService {
      * Initializes voices.
      *
      * @return The voices of this instance
+     * @throws IllegalStateException if voiceRssImpl is null
      */
-    private Set<Voice> initVoices() {
+    private Set<Voice> initVoices() throws IllegalStateException {
+        CachedVoiceRSSCloudImpl voiceRssCloud = voiceRssImpl;
+        if (voiceRssCloud == null) {
+            throw new IllegalStateException("The service is not correctly initialized");
+        }
         Set<Voice> voices = new HashSet<>();
-        for (Locale locale : voiceRssImpl.getAvailableLocales()) {
-            for (String voiceLabel : voiceRssImpl.getAvailableVoices(locale)) {
+        for (Locale locale : voiceRssCloud.getAvailableLocales()) {
+            for (String voiceLabel : voiceRssCloud.getAvailableVoices(locale)) {
                 voices.add(new VoiceRSSVoice(locale, voiceLabel));
             }
         }
@@ -168,10 +182,15 @@ public class VoiceRSSTTSService implements TTSService {
      * Initializes audioFormats
      *
      * @return The audio formats of this instance
+     * @throws IllegalStateException if voiceRssImpl is null
      */
-    private Set<AudioFormat> initAudioFormats() {
+    private Set<AudioFormat> initAudioFormats() throws IllegalStateException {
+        CachedVoiceRSSCloudImpl voiceRssCloud = voiceRssImpl;
+        if (voiceRssCloud == null) {
+            throw new IllegalStateException("The service is not correctly initialized");
+        }
         Set<AudioFormat> audioFormats = new HashSet<>();
-        for (String codec : voiceRssImpl.getAvailableAudioCodecs()) {
+        for (String codec : voiceRssCloud.getAvailableAudioCodecs()) {
             switch (codec) {
                 case "MP3":
                     audioFormats.add(new AudioFormat(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3, null, 16, 64000,
@@ -271,15 +290,18 @@ public class VoiceRSSTTSService implements TTSService {
      * @throws TTSException if {@code format} is not supported
      */
     private String getApiAudioFormat(AudioFormat format) throws TTSException {
-        final int bitDepth = format.getBitDepth() != null ? format.getBitDepth() : 16;
-        final Long frequency = format.getFrequency() != null ? format.getFrequency() : 44_100L;
+        final Integer formatBitDepth = format.getBitDepth();
+        final int bitDepth = formatBitDepth != null ? formatBitDepth.intValue() : 16;
+        final Long formatFrequency = format.getFrequency();
+        final Long frequency = formatFrequency != null ? formatFrequency.longValue() : 44_100L;
         final String apiFrequency = FREQUENCY_MAP.get(frequency);
 
         if (apiFrequency == null || (bitDepth != 8 && bitDepth != 16)) {
             throw new TTSException("Unsupported audio format: " + format);
         }
 
-        switch (format.getCodec() != null ? format.getCodec() : AudioFormat.CODEC_PCM_SIGNED) {
+        String codec = format.getCodec();
+        switch (codec != null ? codec : AudioFormat.CODEC_PCM_SIGNED) {
             case AudioFormat.CODEC_PCM_ALAW:
                 return "alaw_" + apiFrequency + "_mono";
             case AudioFormat.CODEC_PCM_ULAW:
@@ -310,7 +332,7 @@ public class VoiceRSSTTSService implements TTSService {
     }
 
     @Override
-    public String getLabel(Locale locale) {
+    public String getLabel(@Nullable Locale locale) {
         return "VoiceRSS";
     }
 }
index 6e9fed935f98ae759f3931a50098b7f758bb8f16..9c9214ebbd342ed564399715dead98af885c2b13 100644 (file)
@@ -16,6 +16,7 @@ import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.PrintStream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.voice.voicerss.internal.cloudapi.CachedVoiceRSSCloudImpl;
@@ -73,7 +74,10 @@ public class CreateTTSCache {
             File inputFile = new File(inputFileName);
             if (!inputFile.exists()) {
                 usage();
-                System.err.println("File " + inputFileName + " not found");
+                PrintStream printStream = System.err;
+                if (printStream != null) {
+                    printStream.println("File " + inputFileName + " not found");
+                }
                 return RC_INPUT_FILE_NOT_FOUND;
             }
             generateCacheForFile(apiKey, cacheDir, locale, voice, codec, format, inputFileName);
@@ -85,22 +89,26 @@ public class CreateTTSCache {
     }
 
     private void usage() {
-        System.out.println("Usage: java org.openhab.voice.voicerss.tool.CreateTTSCache <args>");
-        System.out.println(
+        PrintStream printStream = System.out;
+        if (printStream == null) {
+            return;
+        }
+        printStream.println("Usage: java org.openhab.voice.voicerss.tool.CreateTTSCache <args>");
+        printStream.println(
                 "Arguments: --api-key <key> <cache-dir> <locale> <voice> { <text> | @inputfile } [ <codec> <format> ]");
-        System.out.println("  key       the VoiceRSS API Key, e.g. \"123456789\"");
-        System.out.println("  cache-dir is directory where the files will be stored, e.g. \"voicerss-cache\"");
-        System.out.println("  locale    the language locale, has to be valid, e.g. \"en-us\", \"de-de\"");
-        System.out.println("  voice     the voice, \"default\" for the default voice");
-        System.out.println("  text      the text to create audio file for, e.g. \"Hello World\"");
-        System.out.println(
+        printStream.println("  key       the VoiceRSS API Key, e.g. \"123456789\"");
+        printStream.println("  cache-dir is directory where the files will be stored, e.g. \"voicerss-cache\"");
+        printStream.println("  locale    the language locale, has to be valid, e.g. \"en-us\", \"de-de\"");
+        printStream.println("  voice     the voice, \"default\" for the default voice");
+        printStream.println("  text      the text to create audio file for, e.g. \"Hello World\"");
+        printStream.println(
                 "  inputfile a name of a file, where all lines will be translatet to text, e.g. \"@message.txt\"");
-        System.out.println("  codec     the audio codec, \"MP3\", \"WAV\", \"OGG\" or \"AAC\", \"MP3\" by default");
-        System.out.println("  format    the audio format, \"44khz_16bit_mono\" by default");
-        System.out.println();
-        System.out.println(
+        printStream.println("  codec     the audio codec, \"MP3\", \"WAV\", \"OGG\" or \"AAC\", \"MP3\" by default");
+        printStream.println("  format    the audio format, \"44khz_16bit_mono\" by default");
+        printStream.println();
+        printStream.println(
                 "Sample: java org.openhab.voice.voicerss.tool.CreateTTSCache --api-key 1234567890 cache en-US default @messages.txt");
-        System.out.println();
+        printStream.println();
     }
 
     private void generateCacheForFile(String apiKey, String cacheDir, String locale, String voice, String codec,
@@ -117,19 +125,29 @@ public class CreateTTSCache {
 
     private void generateCacheForMessage(String apiKey, String cacheDir, String locale, String voice, String codec,
             String format, String msg) throws IOException {
+        PrintStream printStream;
         String trimmedMsg = msg.trim();
         if (trimmedMsg.length() == 0) {
-            System.err.println("Ignore msg=''");
+            printStream = System.err;
+            if (printStream != null) {
+                printStream.println("Ignore msg=''");
+            }
             return;
         }
         try {
             CachedVoiceRSSCloudImpl impl = new CachedVoiceRSSCloudImpl(cacheDir, false);
             File cachedFile = impl.getTextToSpeechAsFile(apiKey, trimmedMsg, locale, voice, codec, format);
-            System.out.println("Created cached audio for locale='" + locale + "', voice='" + voice + "', msg='"
-                    + trimmedMsg + "' to file=" + cachedFile);
+            printStream = System.out;
+            if (printStream != null) {
+                printStream.println("Created cached audio for locale='" + locale + "', voice='" + voice + "', msg='"
+                        + trimmedMsg + "' to file=" + cachedFile);
+            }
         } catch (IllegalStateException | IOException ex) {
-            System.err.println("Failed to create cached audio for locale='" + locale + "', voice='" + voice + "',msg='"
-                    + trimmedMsg + "'");
+            printStream = System.err;
+            if (printStream != null) {
+                printStream.println("Failed to create cached audio for locale='" + locale + "', voice='" + voice
+                        + "',msg='" + trimmedMsg + "'");
+            }
         }
     }
 }