BeanShell-Filter
Diese Seite enthält einige Beispiele für die Verwendung von BeanShell-Filtern. Der angegebene Code muss jeweils in das Textfeld einer BeanShell-Filterkomponente kopiert werden.
Inhaltsverzeichnis
Sendungen mit Bildern
import devplugin.beanshell.BeanShellProgramFilterIf;
import devplugin.Program;
import devplugin.ProgramFieldType;
accept(Program p) {
if(p.getBinaryField(ProgramFieldType.PICTURE_TYPE) != null)
return true;
return false;
}
return (BeanShellProgramFilterIf) this;
Temporär alle Premiere-Sendungen ausblenden
import devplugin.beanshell.BeanShellProgramFilterIf;
import devplugin.Program;
accept(Program p) {
String s=p.getChannel().toString();
return (-1==s.indexOf("Premiere"));
}
return (BeanShellProgramFilterIf) this;
Sendungen, bei denen der Regisseur auch Schauspieler ist
import devplugin.beanshell.BeanShellProgramFilterIf;
import devplugin.Program;
import devplugin.ProgramFieldType;
accept(Program p) {
String director = p.getTextField(ProgramFieldType.DIRECTOR_TYPE);
String actors = p.getTextField(ProgramFieldType.ACTOR_LIST_TYPE);
if (director != null && actors != null) {
if (actors.indexOf(director) >= 0) {
return true;
}
}
return false;
}
return (BeanShellProgramFilterIf) this;
Dynamischer BeanShell-Filter als CSV-File-Interface
Die bislang vorgestellten Skripte führen zu statischen Filterkomponenten vom Typ BeanShell-Filter. Deren Funktionsweise ist ausschließlich durch das Skript und den Datenbestand im TV-Browser bestimmt.
Mit der Filterkomponente BeanShell-Filter kann man auch dynamische Filterkomponenten erstellen. Das hier vorgestellte Skript dient zum Auslesen einer CSV-Datei. Da die Funktionsweise des Filters vom Inhalt der CSV-Datei abhängt und die CSV-Datei jederzeit modifiziert werden kann, ist diese Filterkomponente dynamisch.
In diesem konkreten Beispiel enthält die CSV-Datei episodes.csv Sendungsinformationen in der Form Sendungstitel;Episodentitel. Diese werden mit den korrespondierenden aktuellen Daten im TV-Browser abgeglichen. Der resultierende Filter schließt alle Episoden aus der CSV-Datei ein, die im aktuellen Datenbestand des TV-Browsers enthalten sind.
Hinweis:
Dies ist natürlich nur ein Beispiel für einen dynamischen BeanShell-Filter. Die Daten können auch z. B. in Form eines Excel-Sheets oder einer XML-Datei vorliegen oder aus einer SQL-Datenbank ausgelesen werden. Dazu muss dann natürlich ein entsprechendes Skript erstellt werden.
Ebenso können auf diesem Weg auch andere Parameter als Sendungstitel und Episodentitel abgeglichen werden. Auch hierfür ist natürlich eine Anpassung des Skriptes erforderlich.
Die Wahl einer CSV-Datei als Datenschnittstelle erfolgte bewusst, weil sich die meisten Schnittstellenprobleme darauf reduzieren lassen. Die CSV-Datei stellt diesbezüglich also quasi den "kleinsten gemeinsamen Nenner" dar. In diesem Sinne ist die hier vorgestellte Lösung universell verwendbar.
// Beanshell-Filter: CSV file interface
import devplugin.beanshell.BeanShellProgramFilterIf;
import devplugin.Program;
import devplugin.ProgramFieldType;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
accept(Program prog) throws IOException {
// Reading program data
String title = prog.getTextField(ProgramFieldType.TITLE_TYPE);
String episode = prog.getTextField(ProgramFieldType.EPISODE_TYPE);
// Program data comparison preparation
title = prepareForComparison(title);
episode = prepareForComparison(episode);
// CSV file settings
String file = "D:\\Portable Applications\\Platform\\PortableApps\\TV Browser\\custom\\data\\BeanShell\\episodes.csv";
String separator = ";";
String line = "";
// Program data check
if ((title != null) && (title.trim().length() > 0) && (episode != null) && (episode.trim().length() > 0)){
try{
// Read CSV file
BufferedReader br = new BufferedReader(new FileReader(file));
line = br.readLine();
while (line != null){
line = line.trim();
String[] lineParts = line.split(separator);
// CSV data comparison preparation
String favTitle = prepareForComparison(lineParts[0]);
String favEpisode = prepareForComparison(lineParts[1]);
// Data comparison
if (title.trim().equals(favTitle) && episode.trim().equals(favEpisode)){
// Close reader
closeReader(br);
return true;
}
line = br.readLine();
}
// Close reader;
closeReader(br);
return false;
}catch (IOException ioe) {
// Close reader
closeReader(br);
throw ioe;
}
}else{
// Program data check failed
return false;
}
}
private String prepareForComparison(String unpreparedString){
String preparedString = "";
preparedString = unpreparedString;
// Set to lower case
preparedString = preparedString.toLowerCase();
// Special alphabetic character handling
preparedString = preparedString.replaceAll("\00df", "ss"); // replace ß by ss
preparedString = preparedString.replaceAll("\00e4", "ae"); // replace ä by ae
preparedString = preparedString.replaceAll("\00f6", "oe"); // replace ö by oe
preparedString = preparedString.replaceAll("\00fc", "ue"); // replace ü by ue
// Non-numeric and non-alphabetic character handling
preparedString = preparedString.replaceAll("[^0-9a-z]", "");
// Trim the string
preparedString = preparedString.trim();
return preparedString;
}
private void closeReader (BufferedReader br) throws IOException {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
throw e;
}
}
return (BeanShellProgramFilterIf) this;
Beispiel für eine CSV-Datei:
Dies ist ein Beispiel für eine CSV-Datei episodes.csv, die vom obigen Skript ausgelesen werden kann.
Die Rosenheim-Cops;Ein Abgang mit Blubb
Die Rosenheim-Cops;Zu Tode gesteigert
Die Rosenheim-Cops;Tot im Netz
Um Himmels Willen;Miss Kaltenthal
Um Himmels Willen;Bloßgestellt
Falling Skies;Eine dunkle Nacht
Gotham;Arkham
Anwendung:
Das vorgestellte Beanshell-Skript kann in Kombination mit den Plugins Filter-Info-Icons und SwitchPlugin zur Konfiguration einer offenen bidirektionalen Schnittstelle verwendet werden.
Performance:
Bei der Verwendung von Schnittstellen ist stets auch deren Performance ein sehr wichtiger Aspekt. Diesbezügliche Tests haben für das hier betrachtete BeanShell-Skript für eine CSV-Datei mit 1000 Datensätzen eine zufriedenstellende Performance gezeigt. Daher stellt dieser Ansatz für Datenbestände in dieser Größenordnung eine gute Lösung dar.
Für größere Datenmengen ist dieser Ansatz jedoch ungeeignet. Hierfür steht mit der CSV-Datei-Filterkomponente eine hinsichtlich der Performance weitaus leistungsstärkere Lösung zur Verfügung.
Statiische Variante:
Die Verwendung einer CSV-Datei mit konstantem Inhalt führt zu einer statischen Variante dieser Schnittstelle. Mit dieser Variante lassen sich bei Bedarf sehr komplexe Filter erzeugen.