@@ -72,6 +72,15 @@ public class XMLResponseHandler extends DefaultHandler {
72
72
73
73
private Map <Integer , ContentItem > playerPresets ;
74
74
75
+ /**
76
+ * String builder to collect text content.
77
+ * <p>
78
+ * Background: {@code characters()} may be called multiple times for the same
79
+ * text content in case there are entities like {@code '} inside the
80
+ * content.
81
+ */
82
+ private StringBuilder textContent = new StringBuilder ();
83
+
75
84
/**
76
85
* Creates a new instance of this class
77
86
*
@@ -96,6 +105,7 @@ public void startElement(@Nullable String uri, @Nullable String localName, @Null
96
105
state = XMLHandlerState .Unprocessed ; // set default value; we avoid default in select to have the compiler
97
106
// showing a
98
107
// warning for unhandled states
108
+ textContent = new StringBuilder ();
99
109
100
110
switch (curState ) {
101
111
case INIT :
@@ -475,6 +485,27 @@ public void endElement(String uri, String localName, String qName) throws SAXExc
475
485
case Group :
476
486
handler .handleGroupUpdated (masterDeviceId );
477
487
break ;
488
+ case NowPlayingAlbum :
489
+ updateNowPlayingAlbum (new StringType (textContent .toString ()));
490
+ break ;
491
+ case NowPlayingArtist :
492
+ updateNowPlayingArtist (new StringType (textContent .toString ()));
493
+ break ;
494
+ case NowPlayingDescription :
495
+ updateNowPlayingDescription (new StringType (textContent .toString ()));
496
+ break ;
497
+ case NowPlayingGenre :
498
+ updateNowPlayingGenre (new StringType (textContent .toString ()));
499
+ break ;
500
+ case NowPlayingStationLocation :
501
+ updateNowPlayingStationLocation (new StringType (textContent .toString ()));
502
+ break ;
503
+ case NowPlayingStationName :
504
+ updateNowPlayingStationName (new StringType (textContent .toString ()));
505
+ break ;
506
+ case NowPlayingTrack :
507
+ updateNowPlayingTrack (new StringType (textContent .toString ()));
508
+ break ;
478
509
default :
479
510
// no actions...
480
511
break ;
@@ -483,8 +514,11 @@ public void endElement(String uri, String localName, String qName) throws SAXExc
483
514
484
515
@ Override
485
516
public void characters (char [] ch , int start , int length ) throws SAXException {
486
- logger .trace ("{}: Text data during {}: '{}'" , handler .getDeviceName (), state , new String (ch , start , length ));
517
+ String string = new String (ch , start , length );
518
+ logger .trace ("{}: Text data during {}: '{}'" , handler .getDeviceName (), state , string );
519
+
487
520
super .characters (ch , start , length );
521
+
488
522
switch (state ) {
489
523
case INIT :
490
524
case Msg :
@@ -507,8 +541,7 @@ public void characters(char[] ch, int start, int length) throws SAXException {
507
541
case Zone :
508
542
case ZoneUpdated :
509
543
case Sources :
510
- logger .debug ("{}: Unexpected text data during {}: '{}'" , handler .getDeviceName (), state ,
511
- new String (ch , start , length ));
544
+ logger .debug ("{}: Unexpected text data during {}: '{}'" , handler .getDeviceName (), state , string );
512
545
break ;
513
546
case BassMin : // @TODO - find out how to dynamically change "channel-type" bass configuration
514
547
case BassMax : // based on these values...
@@ -518,38 +551,37 @@ public void characters(char[] ch, int start, int length) throws SAXException {
518
551
// this are currently unprocessed values.
519
552
break ;
520
553
case BassCapabilities :
521
- logger .debug ("{}: Unexpected text data during {}: '{}'" , handler .getDeviceName (), state ,
522
- new String (ch , start , length ));
554
+ logger .debug ("{}: Unexpected text data during {}: '{}'" , handler .getDeviceName (), state , string );
523
555
break ;
524
556
case Unprocessed :
525
557
// drop quietly..
526
558
break ;
527
559
case BassActual :
528
- commandExecutor .updateBassLevelGUIState (new DecimalType (new String ( ch , start , length ) ));
560
+ commandExecutor .updateBassLevelGUIState (new DecimalType (string ));
529
561
break ;
530
562
case InfoName :
531
- setConfigOption (DEVICE_INFO_NAME , new String ( ch , start , length ) );
563
+ setConfigOption (DEVICE_INFO_NAME , string );
532
564
break ;
533
565
case InfoType :
534
- setConfigOption (DEVICE_INFO_TYPE , new String ( ch , start , length ) );
535
- setConfigOption (PROPERTY_MODEL_ID , new String ( ch , start , length ) );
566
+ setConfigOption (DEVICE_INFO_TYPE , string );
567
+ setConfigOption (PROPERTY_MODEL_ID , string );
536
568
break ;
537
569
case InfoModuleType :
538
- setConfigOption (PROPERTY_HARDWARE_VERSION , new String ( ch , start , length ) );
570
+ setConfigOption (PROPERTY_HARDWARE_VERSION , string );
539
571
break ;
540
572
case InfoFirmwareVersion :
541
- String [] fwVersion = new String ( ch , start , length ) .split (" " );
573
+ String [] fwVersion = string .split (" " );
542
574
setConfigOption (PROPERTY_FIRMWARE_VERSION , fwVersion [0 ]);
543
575
break ;
544
576
case BassAvailable :
545
- boolean bassAvailable = Boolean .parseBoolean (new String ( ch , start , length ) );
577
+ boolean bassAvailable = Boolean .parseBoolean (string );
546
578
commandExecutor .setBassAvailable (bassAvailable );
547
579
break ;
548
580
case NowPlayingAlbum :
549
- updateNowPlayingAlbum ( new StringType ( new String ( ch , start , length )) );
581
+ textContent . append ( string );
550
582
break ;
551
583
case NowPlayingArt :
552
- String url = new String ( ch , start , length ) ;
584
+ String url = string ;
553
585
if (url .startsWith ("http" )) {
554
586
// We download the cover art in a different thread to not delay the other operations
555
587
handler .getScheduler ().submit (() -> {
@@ -565,60 +597,60 @@ public void characters(char[] ch, int start, int length) throws SAXException {
565
597
}
566
598
break ;
567
599
case NowPlayingArtist :
568
- updateNowPlayingArtist ( new StringType ( new String ( ch , start , length )) );
600
+ textContent . append ( string );
569
601
break ;
570
602
case ContentItemItemName :
571
- contentItem .setItemName (new String ( ch , start , length ) );
603
+ contentItem .setItemName (string );
572
604
break ;
573
605
case ContentItemContainerArt :
574
- contentItem .setContainerArt (new String ( ch , start , length ) );
606
+ contentItem .setContainerArt (string );
575
607
break ;
576
608
case NowPlayingDescription :
577
- updateNowPlayingDescription ( new StringType ( new String ( ch , start , length )) );
609
+ textContent . append ( string );
578
610
break ;
579
611
case NowPlayingGenre :
580
- updateNowPlayingGenre ( new StringType ( new String ( ch , start , length )) );
612
+ textContent . append ( string );
581
613
break ;
582
614
case NowPlayingPlayStatus :
583
- String playPauseState = new String ( ch , start , length ) ;
615
+ String playPauseState = string ;
584
616
if ("PLAY_STATE" .equals (playPauseState ) || "BUFFERING_STATE" .equals (playPauseState )) {
585
617
commandExecutor .updatePlayerControlGUIState (PlayPauseType .PLAY );
586
618
} else if ("STOP_STATE" .equals (playPauseState ) || "PAUSE_STATE" .equals (playPauseState )) {
587
619
commandExecutor .updatePlayerControlGUIState (PlayPauseType .PAUSE );
588
620
}
589
621
break ;
590
622
case NowPlayingStationLocation :
591
- updateNowPlayingStationLocation ( new StringType ( new String ( ch , start , length )) );
623
+ textContent . append ( string );
592
624
break ;
593
625
case NowPlayingStationName :
594
- updateNowPlayingStationName ( new StringType ( new String ( ch , start , length )) );
626
+ textContent . append ( string );
595
627
break ;
596
628
case NowPlayingTrack :
597
- updateNowPlayingTrack ( new StringType ( new String ( ch , start , length )) );
629
+ textContent . append ( string );
598
630
break ;
599
631
case VolumeActual :
600
- commandExecutor .updateVolumeGUIState (new PercentType (Integer .parseInt (new String ( ch , start , length ) )));
632
+ commandExecutor .updateVolumeGUIState (new PercentType (Integer .parseInt (string )));
601
633
break ;
602
634
case VolumeMuteEnabled :
603
- volumeMuteEnabled = Boolean .parseBoolean (new String ( ch , start , length ) );
635
+ volumeMuteEnabled = Boolean .parseBoolean (string );
604
636
commandExecutor .setCurrentMuted (volumeMuteEnabled );
605
637
break ;
606
638
case MasterDeviceId :
607
639
if (masterDeviceId != null ) {
608
- masterDeviceId .macAddress = new String ( ch , start , length ) ;
640
+ masterDeviceId .macAddress = string ;
609
641
}
610
642
break ;
611
643
case GroupName :
612
644
if (masterDeviceId != null ) {
613
- masterDeviceId .groupName = new String ( ch , start , length ) ;
645
+ masterDeviceId .groupName = string ;
614
646
}
615
647
break ;
616
648
case DeviceId :
617
- deviceId = new String ( ch , start , length ) ;
649
+ deviceId = string ;
618
650
break ;
619
651
case DeviceIp :
620
652
if (masterDeviceId != null && Objects .equals (masterDeviceId .macAddress , deviceId )) {
621
- masterDeviceId .host = new String ( ch , start , length ) ;
653
+ masterDeviceId .host = string ;
622
654
}
623
655
break ;
624
656
default :
0 commit comments