/* * This file is part of Quelea, free projection software for churches. * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.quelea.services.importexport; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.quelea.data.displayable.SongDisplayable; import org.quelea.services.utils.LoggerUtils; import org.quelea.services.utils.UnicodeReader; import org.quelea.windows.main.StatusPanel; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * A parser for importing Opensong databases * <p> * @author Michael */ public class OpensongParser implements SongParser { private static final Logger LOGGER = LoggerUtils.getLogger(); @Override public List<SongDisplayable> getSongs(File location, StatusPanel statusPanel) throws IOException { try (ZipFile file = new ZipFile(location, Charset.forName("Cp437"))) { List<SongDisplayable> ret = new ArrayList<>(); final Enumeration<? extends ZipEntry> entries = file.entries(); while (entries.hasMoreElements()) { String fileName = null; try { final ZipEntry entry = entries.nextElement(); fileName = entry.getName(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new InputSource(new UnicodeReader(file.getInputStream(entry), "UTF-8"))); NodeList list = doc.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { if (list.item(i).getNodeName().equalsIgnoreCase("song")) { SongDisplayable displayable = getDisplayable(list.item(i)); if (displayable != null) { ret.add(displayable); } } } } catch (IOException | ParserConfigurationException | SAXException ex) { LOGGER.log(Level.WARNING, "Error importing opensong: " + fileName, ex); } } return ret; } } /** * Get a song displayable from a song node. * * @param root the "song" root node * @return the SongDisplayable represented by this node. */ private SongDisplayable getDisplayable(Node root) { NodeList nl = root.getChildNodes(); String title = ""; String author = ""; String lyrics = ""; String copyright = ""; String key = ""; String ccli = ""; String capo = ""; for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node.getNodeName().equalsIgnoreCase("title")) { title = node.getTextContent(); } else if (node.getNodeName().equalsIgnoreCase("author")) { author = node.getTextContent(); } else if (node.getNodeName().equalsIgnoreCase("copyright")) { copyright = node.getTextContent(); } else if (node.getNodeName().equalsIgnoreCase("key")) { key = node.getTextContent(); } else if (node.getNodeName().equalsIgnoreCase("ccli")) { ccli = node.getTextContent(); } else if (node.getNodeName().equalsIgnoreCase("capo")) { capo = node.getTextContent(); } else if (node.getNodeName().equalsIgnoreCase("lyrics")) { lyrics = node.getTextContent(); } } if (title.isEmpty()) { return null; } SongDisplayable ret = new SongDisplayable(title, author); ret.setLyrics(processLyrics(lyrics)); ret.setCopyright(copyright); ret.setKey(key); ret.setCcli(ccli); ret.setCapo(capo); return ret; } private String processLyrics(String lyrics) { StringBuilder ret = new StringBuilder(); String[] arr = lyrics.split("\n"); boolean ignoreVerse = false; for (String line : arr) { line = line.trim(); if (line.startsWith("[") && line.endsWith("]") && line.length() > 2) { ignoreVerse = false; String sectionTitle = line.substring(1, line.length() - 1); if (sectionTitle.startsWith("V")) { if (sectionTitle.length() > 1) { line = "Verse " + sectionTitle.substring(1); } else { line = "Verse"; } } else if (sectionTitle.startsWith("C")) { if (sectionTitle.length() > 1) { line = "Chorus " + sectionTitle.substring(1); } else { line = "Chorus"; } } else if (sectionTitle.startsWith("T")) { if (sectionTitle.length() > 1) { line = "Tag " + sectionTitle.substring(1); } else { line = "Tag"; } } else if (sectionTitle.startsWith("B")) { if (sectionTitle.length() > 1) { line = "Bridge " + sectionTitle.substring(1); } else { line = "Bridge"; } } else { line = "Verse"; } } else if (line.startsWith(".")) { line = line.substring(1); } else if (line.endsWith("||")) { line = line.substring(0, line.length() - 2) + "\n"; } else if (line.equals("---")) { line = ""; } else if (line.startsWith(";")) { ignoreVerse = true; } line = line.replace("|", "\n"); if (!ignoreVerse) { ret.append(line).append("\n"); } } return ret.toString(); } }