Add StAX html writer

- Add StAX html writer (same style as the custom writer)
- Add option in UI
This commit is contained in:
Tanguy Herbron 2018-10-14 22:27:03 +02:00
parent a439511e47
commit ca7608ecab
6 changed files with 268 additions and 108 deletions

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@ import fr.ensim.xml.deezer.dom.DOMSearchAlbums;
import fr.ensim.xml.deezer.dom.DOMSearchAlbumTracks; import fr.ensim.xml.deezer.dom.DOMSearchAlbumTracks;
import fr.ensim.xml.deezer.sax.SAXSearchAlbums; import fr.ensim.xml.deezer.sax.SAXSearchAlbums;
import fr.ensim.xml.deezer.stax.HtmlAlbum; import fr.ensim.xml.deezer.stax.HtmlAlbum;
import fr.ensim.xml.deezer.stax.StAXHtmlAlbum;
/** /**
@ -34,7 +35,7 @@ public class Runner {
ProxyConfiguration.configure(); ProxyConfiguration.configure();
} }
public File start(String searchString) public File start(String searchString, boolean useCustom)
{ {
Logger log = Logger.getLogger(Runner.class); Logger log = Logger.getLogger(Runner.class);
@ -50,7 +51,17 @@ public class Runner {
File fileHtml = new File(listAlbum.get(0).getArtist().getName() + ".html"); File fileHtml = new File(listAlbum.get(0).getArtist().getName() + ".html");
out = new FileOutputStream(fileHtml); out = new FileOutputStream(fileHtml);
if(useCustom)
{
HtmlAlbum.write(listAlbum, out); HtmlAlbum.write(listAlbum, out);
}
else
{
StAXHtmlAlbum.write(listAlbum, out);
}
out.close(); out.close();
if(fileHtml.isFile()) if(fileHtml.isFile())
@ -78,7 +89,7 @@ public class Runner {
return null; return null;
} }
public File start(String searchString, boolean useDom) public File start(String searchString, boolean useDom, boolean useCustom)
{ {
Logger log = Logger.getLogger(Runner.class); Logger log = Logger.getLogger(Runner.class);
@ -100,7 +111,16 @@ public class Runner {
// Ecriture de la page html // Ecriture de la page html
File fileHtml = new File(listAlbum.get(0).getArtist().getName() + ".html"); File fileHtml = new File(listAlbum.get(0).getArtist().getName() + ".html");
out = new FileOutputStream(fileHtml); out = new FileOutputStream(fileHtml);
if(useCustom)
{
HtmlAlbum.write(listAlbum, out); HtmlAlbum.write(listAlbum, out);
}
else
{
StAXHtmlAlbum.write(listAlbum, out);
}
out.close(); out.close();
// Ouverture de la page // Ouverture de la page

View File

@ -0,0 +1,157 @@
package fr.ensim.xml.deezer.stax;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.log4j.Logger;
import fr.ensim.xml.deezer.data.Album;
import fr.ensim.xml.deezer.data.Track;
public class StAXHtmlAlbum {
private static Logger log = Logger.getLogger(StAXHtmlAlbum.class);
public static void write(List<Album> albums, OutputStream outputStream) throws IOException
{
log.debug(">>write");
XMLOutputFactory factoty = XMLOutputFactory.newInstance();
FileWriter fileWriter = new FileWriter(albums.get(0).getArtist().getName() + ".html");
try {
XMLStreamWriter writer = factoty.createXMLStreamWriter(fileWriter);
writer.writeStartDocument();
writer.writeStartElement("html");
writer.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
writer.writeStartElement("head");
writer.writeStartElement("link");
writer.writeAttribute("rel", "stylesheet");
writer.writeAttribute("href", "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css");
writer.writeEndElement(); //Close link
writer.writeStartElement("script");
writer.writeAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js");
writer.writeEndElement(); //Close script
writer.writeEndElement(); //Close head
writer.writeStartElement("body");
writer.writeStartElement("div");
writer.writeStartElement("nav");
writer.writeAttribute("style", "background-color: #3A3A3A");
writer.writeStartElement("div");
writer.writeAttribute("class", "nav-wrapper");
writer.writeStartElement("a");
writer.writeAttribute("href", "#");
writer.writeAttribute("class", "brand-logo");
writer.writeCharacters(albums.get(0).getArtist().getName());
writer.writeEndElement(); // Close a
writer.writeEndElement(); // Close div
writer.writeEndElement(); // Close nav
writer.writeEndElement(); // Close div
writer.writeStartElement("div");
writer.writeAttribute("class", "container");
generateAlbumElements(writer, albums);
writer.writeEndElement(); // Close div
writer.writeEndElement(); // Close body
writer.writeEndElement(); // Close html
writer.writeEndDocument();
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
fileWriter.close();
}
}
private static void generateAlbumElements(XMLStreamWriter writer, List<Album> albums) throws XMLStreamException
{
int i = 0;
while(i < albums.size())
{
writer.writeStartElement("div");
writer.writeAttribute("class", "row");
generateAlbumCards(writer
, albums.get(i).getTitle()
, albums.get(i).getCover()
, albums.get(i).getTracks());
if(albums.size() > i+1)
{
i++;
generateAlbumCards(writer
, albums.get(i).getTitle()
, albums.get(i).getCover()
, albums.get(i).getTracks());
}
i++;
writer.writeEndElement();
}
}
private static void generateAlbumCards(XMLStreamWriter writer, String title, String cover, List<Track> tracks) throws XMLStreamException
{
writer.writeStartElement("div");
writer.writeAttribute("class", "col s12 m6");
writer.writeStartElement("div");
writer.writeAttribute("class", "card blue-grey darken-1");
writer.writeStartElement("div");
writer.writeAttribute("class", "card-content white-text");
writer.writeStartElement("ul");
writer.writeAttribute("class", "collection with-header blue-grey darken-1");
writer.writeStartElement("li");
writer.writeAttribute("class", "collection-header blue-grey darken-1");
writer.writeStartElement("div");
writer.writeStartElement("img");
writer.writeAttribute("class", "responsive-img circle");
writer.writeAttribute("style", "max-height: 50px; max-width: 50px");
writer.writeAttribute("src", cover);
writer.writeEndElement(); // Close img
writer.writeStartElement("span");
writer.writeAttribute("class", "card-title");
writer.writeAttribute("style", "display: inline-block;");
writer.writeCharacters(title);
writer.writeEndElement(); // Close span
writer.writeEndElement(); // Close div
writer.writeEndElement(); // Close li
generateTracks(writer, tracks);
writer.writeEndElement(); // Close ul
writer.writeEndElement(); // Close div
writer.writeEndElement(); // Close div
writer.writeEndElement(); // Close div
}
private static void generateTracks(XMLStreamWriter writer, List<Track> tracks) throws XMLStreamException
{
for(int i = 0; i < tracks.size(); i++)
{
writer.writeStartElement("li");
writer.writeAttribute("class", "collection-item blue-grey darken-1");
writer.writeStartElement("span");
writer.writeCharacters(tracks.get(i).getTitle());
writer.writeEndElement(); // Close span
writer.writeStartElement("audio controls");
writer.writeAttribute("style", "display: block");
writer.writeStartElement("source");
writer.writeAttribute("src", tracks.get(i).getPreview());
writer.writeAttribute("type", "audio/mpeg");
writer.writeEndElement(); // Close source
writer.writeEndElement(); // Close audio controls
writer.writeEndElement(); // Close li
}
}
}

View File

@ -10,52 +10,53 @@
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.web.WebView?> <?import javafx.scene.web.WebView?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8.0.181" xmlns:fx="http://javafx.com/fxml/1"> <VBox maxHeight="Infinity" maxWidth="Infinity" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
<GridPane prefHeight="400.0" prefWidth="640.0"> <GridPane maxHeight="Infinity" maxWidth="Infinity" prefHeight="460.0" prefWidth="640.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="7.0" prefWidth="640.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="Infinity" minWidth="7.0" prefWidth="640.0" />
<ColumnConstraints /> <ColumnConstraints />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints maxHeight="89.0" minHeight="0.0" prefHeight="27.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="90.0" minHeight="20.0" prefHeight="25.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="188.0" minHeight="10.0" prefHeight="58.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="Infinity" minHeight="10.0" prefHeight="430.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="187.0" minHeight="10.0" prefHeight="187.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="113.0" minHeight="10.0" prefHeight="113.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<WebView fx:id="webView" prefHeight="-1.0" prefWidth="-1.0" GridPane.columnSpan="2" GridPane.rowIndex="1" GridPane.rowSpan="3" /> <WebView fx:id="webView" prefHeight="Infinity" prefWidth="Infinity" GridPane.rowIndex="1" />
<GridPane> <GridPane maxHeight="Infinity" maxWidth="Infinity">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="589.0" minWidth="10.0" prefWidth="460.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="589.0" minWidth="10.0" prefWidth="256.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="113.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="94.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="74.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="98.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="120.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Button fx:id="searchButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Rechercher" GridPane.columnIndex="1" /> <Button fx:id="searchButton" maxHeight="Infinity" maxWidth="Infinity" mnemonicParsing="false" text="Rechercher" GridPane.columnIndex="1" />
<TextField fx:id="searchBar" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" /> <TextField fx:id="searchBar" maxHeight="Infinity" maxWidth="Infinity" />
<MenuButton fx:id="parserSelector" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="35.0" prefWidth="90.0" text="Parser" GridPane.columnIndex="2"> <MenuButton fx:id="parserSelector" maxHeight="Infinity" maxWidth="Infinity" mnemonicParsing="false" prefHeight="35.0" prefWidth="90.0" text="Parser" GridPane.columnIndex="2">
<items> <items>
<MenuItem mnemonicParsing="false" text="XML" fx:id="xmlOption" /> <MenuItem mnemonicParsing="false" text="XML" fx:id="xmlOption" />
<MenuItem fx:id="jsonOption" mnemonicParsing="false" text="JSON" /> <MenuItem fx:id="jsonOption" mnemonicParsing="false" text="JSON" />
</items> </items>
</MenuButton> </MenuButton>
<MenuButton layoutX="397.0" layoutY="10.0" maxHeight="Infinity" maxWidth="Infinity" mnemonicParsing="false" prefHeight="35.0" prefWidth="90.0" text="XML Format" GridPane.columnIndex="3" fx:id="xmlFormatSelector">
<items>
<MenuItem mnemonicParsing="false" text="DOM" fx:id="xmlOption1" />
<MenuItem fx:id="jsonOption1" mnemonicParsing="false" text="SAX/StAX" />
</items>
</MenuButton>
<MenuButton layoutX="455.0" layoutY="10.0" maxHeight="Infinity" maxWidth="Infinity" mnemonicParsing="false" prefHeight="35.0" prefWidth="90.0" text="HTML Generator" GridPane.columnIndex="4" fx:id="htmlGeneratorSelector">
<items>
<MenuItem mnemonicParsing="false" text="Custom" fx:id="xmlOption11" />
<MenuItem fx:id="jsonOption11" mnemonicParsing="false" text="StAX" />
</items>
</MenuButton>
</children> </children>
</GridPane> </GridPane>
<GridPane GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children> </children>
</GridPane> </GridPane>
</children> </children>

View File

@ -21,6 +21,9 @@ import javafx.stage.Stage;
public class MainWindow extends Application { public class MainWindow extends Application {
private boolean useDom;
private boolean useCustom;
@Override @Override
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml")); Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
@ -41,6 +44,12 @@ public class MainWindow extends Application {
final MenuItem xmlOption = menuButton.getItems().get(0); final MenuItem xmlOption = menuButton.getItems().get(0);
final MenuItem jsonOption = menuButton.getItems().get(1); final MenuItem jsonOption = menuButton.getItems().get(1);
final WebView webView = (WebView) scene.lookup("#webView"); final WebView webView = (WebView) scene.lookup("#webView");
final MenuButton formatButton = (MenuButton) scene.lookup("#xmlFormatSelector");
final MenuItem domOption = formatButton.getItems().get(0);
final MenuItem saxOption = formatButton.getItems().get(1);
final MenuButton htmlButton = (MenuButton) scene.lookup("#htmlGeneratorSelector");
final MenuItem customOption = htmlButton.getItems().get(0);
final MenuItem staxOption = htmlButton.getItems().get(1);
searchButton.setOnAction(new EventHandler<ActionEvent>() { searchButton.setOnAction(new EventHandler<ActionEvent>() {
@Override @Override
@ -48,14 +57,14 @@ public class MainWindow extends Application {
if(menuButton.getText().equals(jsonOption.getText())) if(menuButton.getText().equals(jsonOption.getText()))
{ {
Runner runner = new Runner(); Runner runner = new Runner();
File htmlFile = runner.start(searchTextField.getText().replaceAll("\\s", "%20")); File htmlFile = runner.start(searchTextField.getText().replaceAll("\\s", "%20"), useCustom);
WebEngine engine = webView.getEngine(); WebEngine engine = webView.getEngine();
engine.load(htmlFile.toURI().toString()); engine.load(htmlFile.toURI().toString());
} }
else else
{ {
Runner runner = new Runner(); Runner runner = new Runner();
File htmlFile = runner.start(searchTextField.getText().replaceAll("\\s", "%20"), false); File htmlFile = runner.start(searchTextField.getText().replaceAll("\\s", "%20"), useDom, useCustom);
WebEngine engine = webView.getEngine(); WebEngine engine = webView.getEngine();
engine.load(htmlFile.toURI().toString()); engine.load(htmlFile.toURI().toString());
} }
@ -68,6 +77,7 @@ public class MainWindow extends Application {
@Override @Override
public void handle(ActionEvent event) { public void handle(ActionEvent event) {
menuButton.setText(xmlOption.getText()); menuButton.setText(xmlOption.getText());
formatButton.setDisable(false);
} }
}); });
@ -76,6 +86,43 @@ public class MainWindow extends Application {
@Override @Override
public void handle(ActionEvent event) { public void handle(ActionEvent event) {
menuButton.setText(jsonOption.getText()); menuButton.setText(jsonOption.getText());
formatButton.setDisable(true);
}
});
domOption.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
formatButton.setText(domOption.getText());
useDom = true;
}
});
saxOption.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
formatButton.setText(saxOption.getText());
useDom = false;
}
});
customOption.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
htmlButton.setText(customOption.getText());
useCustom = true;
}
});
staxOption.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
htmlButton.setText(staxOption.getText());
useCustom = false;
} }
}); });
} }

View File

@ -1,8 +1,10 @@
17:25:23,069 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbumsTest - >>testCount 22:21:21,043 DEBUG fr.ensim.xml.deezer.AbstractSearchAlbum - >>find author=Shaka%20ponk
17:25:23,071 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbums - >>count 22:21:21,046 DEBUG fr.ensim.xml.deezer.AbstractSearchAlbum - http://api.deezer.com/2.0/search/album?q=Shaka%20ponk
17:25:23,082 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbums - <<count 10 22:21:26,435 DEBUG fr.ensim.json.JSONSearchAlbum - >>readAlbums
17:25:23,082 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbumsTest - <<testCount 22:21:26,445 DEBUG fr.ensim.json.JSONSearchAlbum - <<readAlbums
17:25:23,083 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbumsTest - >>testParse 22:21:26,446 DEBUG fr.ensim.xml.deezer.AbstractSearchAlbum - <<find
17:25:23,083 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbums - >>readAlbums 22:21:26,446 DEBUG fr.ensim.json.JSONSearchAlbumTracks - >>albums
17:25:23,085 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbums - <<readAlbums 22:21:26,447 DEBUG fr.ensim.json.JSONSearchAlbumTracks - http://api.deezer.com/2.0/album/47685332
17:25:23,085 DEBUG fr.ensim.xml.deezer.stax.StAXSearchAlbumsTest - <<testParse 22:21:31,570 DEBUG fr.ensim.json.JSONSearchAlbumTracks - >>find
22:21:31,579 DEBUG fr.ensim.json.JSONSearchAlbumTracks - >>find
22:21:31,580 DEBUG fr.ensim.xml.deezer.stax.StAXHtmlAlbum - >>write