Commit 9cd91587 authored by Daniel Dreibrodt's avatar Daniel Dreibrodt

New XML parsing system: Basis finished but Items still need necessary constructors

parent 0a28a8e6
......@@ -2,8 +2,9 @@
Source: share/ICE_JNIRegistry.dll; DestDir: {app}
Source: LICENSE.TXT; DestDir: {app}
Source: README.TXT; DestDir: {app}; Flags: isreadme
Source: skin.dtd; DestDir: {app}
Source: share/VLCSkinEditor.exe; DestDir: {app}
Source: build/VLCSkinEditor.jar; DestDir: {app}
Source: VLCSkinEditor.jar; DestDir: {app}
Source: lang/English.txt; DestDir: {app}/lang
Source: lang/english/*.txt; DestDir: {app}/lang/english/
[Icons]
......@@ -12,7 +13,7 @@ Name: {group}\Uninstall VLC Skin Editor; Filename: {uninstallexe}
Name: {group}\Online Help; Filename: http://www.videolan.org/vlc/skinedhlp/
[Setup]
OutputBaseFilename=VLCSkinEditor_setup
VersionInfoVersion=0.7.5
VersionInfoVersion=0.8
VersionInfoCompany=VideoLAN
VersionInfoDescription=Setup for the VLC Skin Editor
VersionInfoCopyright=2008 VideoLAN
......@@ -30,7 +31,7 @@ AppPublisherURL=http://www.videolan.org
AppSupportURL=http://www.videolan.org/vlc/skineditor.html
AppUpdatesURL=http://www.videolan.org/vlc/skineditor.html
AppVersion=0.7
AppID={{977C5080-EA08-435D-8901-233A506E1651}
AppID={{977C5080-EA08-435D-8901-233A506E1651}}
AppReadmeFile={app}\README.TXT
UninstallDisplayIcon={app}\VLCSkinEditor.exe
UninstallDisplayName=VLC Skin Editor
......
......@@ -59,6 +59,7 @@
VLCSkinEditor.jar
README.TXT
LICENSE.TXT
skin.dtd
${lang}/*.txt
${lang}/*/*.txt" />
</zip>
......@@ -72,6 +73,7 @@
<fileset dir="." includes="README.TXT
LICENSE.TXT
VLCSkinEditor.jar
skin.dtd
${lang}/*.txt
${lang}/*/*.txt"/>
</zip>
......@@ -103,6 +105,7 @@
<fileset dir="." includes="README.TXT
LICENSE.TXT
VLCSkinEditor.jar
skin.dtd
${lang}/*.txt
${lang}/*/*.txt" />
</tar>
......
<!-- version 2.0
-->
<!ELEMENT Theme (ThemeInfo,(Include|IniFile|Bitmap|BitmapFont|Font|PopupMenu|Window)*)>
<!ATTLIST Theme
version CDATA #REQUIRED
tooltipfont CDATA "defaultfont"
magnet CDATA "15"
alpha CDATA "255"
movealpha CDATA "255"
>
<!-- main elements -->
<!ELEMENT IniFile EMPTY>
<!ATTLIST IniFile
id CDATA #REQUIRED
file CDATA #REQUIRED
>
<!ELEMENT Include EMPTY>
<!ATTLIST Include
file CDATA #REQUIRED
>
<!ELEMENT Bitmap (SubBitmap)*>
<!ATTLIST Bitmap
id CDATA #REQUIRED
file CDATA #REQUIRED
alphacolor CDATA #REQUIRED
nbframes CDATA "1"
fps CDATA "0"
>
<!ELEMENT SubBitmap EMPTY>
<!ATTLIST SubBitmap
id CDATA #REQUIRED
x CDATA #REQUIRED
y CDATA #REQUIRED
width CDATA #REQUIRED
height CDATA #REQUIRED
nbframes CDATA "1"
fps CDATA "0"
>
<!ELEMENT Font EMPTY>
<!ATTLIST Font
id CDATA #REQUIRED
file CDATA #REQUIRED
size CDATA "12"
>
<!ELEMENT BitmapFont EMPTY>
<!ATTLIST BitmapFont
id CDATA #REQUIRED
file CDATA #REQUIRED
type CDATA "digits"
>
<!ELEMENT PopupMenu (MenuItem|MenuSeparator)+>
<!ATTLIST PopupMenu
id CDATA #REQUIRED
>
<!ELEMENT MenuItem EMPTY>
<!ATTLIST MenuItem
label CDATA #REQUIRED
action CDATA "none"
>
<!ELEMENT MenuSeparator EMPTY>
<!ELEMENT ThemeInfo EMPTY>
<!ATTLIST ThemeInfo
name CDATA #IMPLIED
author CDATA #IMPLIED
email CDATA #IMPLIED
webpage CDATA #IMPLIED
>
<!ELEMENT Window (Layout)+>
<!ATTLIST Window
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
dragdrop CDATA "true"
playondrop CDATA "true"
>
<!ELEMENT Layout (Group|Image|Button|Playlist|Slider|RadialSlider|Text|Checkbox|
Anchor|Video|Playtree|Panel)+>
<!ATTLIST Layout
id CDATA "none"
width CDATA #REQUIRED
height CDATA #REQUIRED
minwidth CDATA "-1"
maxwidth CDATA "-1"
minheight CDATA "-1"
maxheight CDATA "-1"
>
<!-- Grouping elements -->
<!ELEMENT Group (Group|Image|Button|Playlist|Slider|RadialSlider|Text|Checkbox|
Anchor|Video|Playtree|Panel)+>
<!ATTLIST Group
x CDATA "0"
y CDATA "0"
>
<!ELEMENT Panel (Group|Image|Button|Playlist|Slider|RadialSlider|Text|Checkbox|
Anchor|Video|Playtree|Panel)+>
<!ATTLIST Panel
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
width CDATA #REQUIRED
height CDATA #REQUIRED
>
<!-- Anchors -->
<!ELEMENT Anchor EMPTY>
<!ATTLIST Anchor
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
priority CDATA #REQUIRED
points CDATA "(0,0)"
range CDATA "10"
>
<!-- Controls -->
<!ELEMENT Image EMPTY>
<!ATTLIST Image
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
image CDATA #REQUIRED
action CDATA "none"
action2 CDATA "none"
resize CDATA "mosaic"
help CDATA ""
>
<!ELEMENT Button EMPTY>
<!ATTLIST Button
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
up CDATA #REQUIRED
down CDATA "none"
over CDATA "none"
action CDATA "none"
tooltiptext CDATA ""
help CDATA ""
>
<!ELEMENT Checkbox EMPTY>
<!ATTLIST Checkbox
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
up1 CDATA #REQUIRED
down1 CDATA "none"
over1 CDATA "none"
up2 CDATA #REQUIRED
down2 CDATA "none"
over2 CDATA "none"
state CDATA #REQUIRED
action1 CDATA "none"
action2 CDATA "none"
tooltiptext1 CDATA ""
tooltiptext2 CDATA ""
help CDATA ""
>
<!ELEMENT Slider (SliderBackground)?>
<!ATTLIST Slider
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
up CDATA #REQUIRED
down CDATA "none"
over CDATA "none"
points CDATA #REQUIRED
thickness CDATA "10"
value CDATA "none"
background CDATA "none"
tooltiptext CDATA ""
help CDATA ""
>
<!ELEMENT SliderBackground EMPTY>
<!ATTLIST SliderBackground
id CDATA "none"
image CDATA #REQUIRED
nbhoriz CDATA "1"
nbvert CDATA "1"
padhoriz CDATA "0"
padvert CDATA "0"
>
<!ELEMENT RadialSlider EMPTY>
<!ATTLIST RadialSlider
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
sequence CDATA #REQUIRED
nbimages CDATA #REQUIRED
minangle CDATA "0"
maxangle CDATA "360"
value CDATA "none"
tooltiptext CDATA ""
help CDATA ""
>
<!ELEMENT Text EMPTY>
<!ATTLIST Text
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
width CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
text CDATA ""
font CDATA #REQUIRED
color CDATA "#000000"
scrolling CDATA "auto"
alignment CDATA "left"
help CDATA ""
>
<!ELEMENT Playlist (Slider)?>
<!ATTLIST Playlist
id CDATA #REQUIRED
visible CDATA "true"
x CDATA "0"
y CDATA "0"
width CDATA "0"
height CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
font CDATA #REQUIRED
bgimage CDATA "none"
fgcolor CDATA "#000000"
playcolor CDATA "#FF0000"
bgcolor1 CDATA "#FFFFFF"
bgcolor2 CDATA "#FFFFFF"
selcolor CDATA "#0000FF"
help CDATA ""
>
<!ELEMENT Playtree (Slider)?>
<!ATTLIST Playtree
id CDATA #REQUIRED
visible CDATA "true"
x CDATA "0"
y CDATA "0"
width CDATA "0"
height CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
font CDATA #REQUIRED
bgimage CDATA "none"
itemimage CDATA "none"
openimage CDATA "none"
closedimage CDATA "none"
fgcolor CDATA "#000000"
playcolor CDATA "#FF0000"
bgcolor1 CDATA "#FFFFFF"
bgcolor2 CDATA "#FFFFFF"
selcolor CDATA "#0000FF"
help CDATA ""
flat CDATA "false"
>
<!ELEMENT Video EMPTY>
<!ATTLIST Video
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
width CDATA "0"
height CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
ykeepratio CDATA "false"
autoresize CDATA "true"
help CDATA ""
>
......@@ -24,6 +24,11 @@ package vlcskineditor;
import java.awt.Component;
import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import javax.swing.JOptionPane;
/**
......@@ -70,4 +75,25 @@ public class Helper {
JOptionPane.showMessageDialog(null,Language.get("ERROR_BROWSE_MSG").replaceAll("%u", url),Language.get("ERROR_BROWSE_TITLE"),JOptionPane.WARNING_MESSAGE);
}
}
/**
* Taken from http://www.rgagnon.com/javadetails/java-0064.html
* @param in Source File
* @param out Destination File
* @throws java.io.IOException
*/
public static void copyFile(File in, File out) throws IOException {
FileChannel inChannel = new FileInputStream(in).getChannel();
FileChannel outChannel = new FileOutputStream(out).getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
}
catch (IOException e) {
throw e;
}
finally {
if (inChannel != null) inChannel.close();
if (outChannel != null) outChannel.close();
}
}
}
......@@ -30,6 +30,8 @@ import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.border.*;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Handles a windows' layout and it's content
......@@ -61,6 +63,28 @@ public class Layout implements ActionListener{
boolean created = false;
/**
* Parses a layout's structure from a given XML node
* @param n The XML node
* @param w_ The parent window
* @param s_ The parent skin manager
*/
public Layout(Node n, Window w_, Skin s_) {
s = s_;
parent = w_;
id = XML.getStringAttributeValue(n, "id", Language.get("UNNAMED").replaceAll("%t",type).replaceAll("%i",String.valueOf(s.getNewId())));
width = XML.getIntAttributeValue(n, "width", width);
height = XML.getIntAttributeValue(n, "height", height);
minwidth = XML.getIntAttributeValue(n, "minwidth", minwidth);
maxwidth = XML.getIntAttributeValue(n, "maxwidth", maxwidth);
minheight = XML.getIntAttributeValue(n, "minheight", minheight);
maxheight = XML.getIntAttributeValue(n, "maxheight", maxheight);
NodeList nodes = n.getChildNodes();
for(int i=0;i<nodes.getLength();i++) {
}
}
/**
* Creates a new Layout from XML.
* @param xmlcode The XML code from which the Layout should be created.
......
......@@ -47,12 +47,12 @@ import vlcskineditor.resources.SubBitmap;
*/
public class Main extends javax.swing.JFrame implements ActionListener, TreeSelectionListener, WindowListener, MouseListener{
private static final long serialVersionUID = 075;
private static final long serialVersionUID = 80;
private final String updateURL_s = "http://www.videolan.org/vlc/skineditor_update.php";
//The version identification of the current build.
public final static String VERSION = "0.7.5.dev";
public final static String VERSION = "0.8.0.dev";
//The directory in which the VLC executable is found
String vlc_dir = "";
//The directory from which VLC loads its skins
......@@ -608,7 +608,7 @@ public class Main extends javax.swing.JFrame implements ActionListener, TreeSele
RegistryKey vlc_key = Registry.openSubkey(Registry.HKEY_LOCAL_MACHINE,"Software\\VideoLAN\\VLC",RegistryKey.ACCESS_READ);
String installDir = vlc_key.getStringValue("InstallDir");
vlc_dir = installDir+File.separator;
vlc_skins_dir = vlc_dir+"skins";
vlc_skins_dir = vlc_dir+"skins\\";
}
catch (Exception e) {
System.err.println("Could not read VLC installation directory from Registry. VLC might not be properly installed.");
......@@ -638,7 +638,8 @@ public class Main extends javax.swing.JFrame implements ActionListener, TreeSele
openFile();
}
else {
System.exit(0);
saved = true;
exit();
}
}
/**
......
......@@ -95,18 +95,24 @@ public class Skin implements ActionListener{
JTextField theme_magnet_tf, theme_alpha_tf, theme_movealpha_tf;
JButton theme_ok_btn, theme_cancel_btn, theme_help_btn;
//Manager of the global variables
public GlobalVariables gvars = new GlobalVariables(this);
//Central window handle for all editing dialogs of res/win/layout/items
public JFrame edit_frame;
//Default indentation of generated XML code
//Default indentation of generated XML code (2 spaces)
public static String indentation = " ";
/**
* Constructs a new skin manager
* @param m_ The current instance of the main interface, needed for GUI interaction
*/
public Skin(Main m_) {
m=m_;
}
/** Creates the file in which to save the new skin **/
/**
* Creates a new empty skins in the given file
* @param f The target file
**/
public void createNew(File f) {
skinfile=f;
skinfolder = f.getParentFile().getAbsolutePath()+File.separator;
......@@ -117,15 +123,19 @@ public class Skin implements ActionListener{
JOptionPane.showMessageDialog(null,Language.get("ERROR_NEWSKIN_TITLE")+"\n\n"+ex.toString(),Language.get("ERROR_NEWSKIN_TITLE"),JOptionPane.ERROR_MESSAGE);
}
}
/** Parses an XML file **/
/**
* Handles the parsing of a given file into the skin structure
* @param f
*/
public void open(File f) {
resources.clear();
windows.clear();
skinfile=f;
skinfolder = f.getParentFile().getAbsolutePath()+File.separator;
try {
parse(f);
//parseXML(f);
//parse(f);
parseXML(f);
}
catch (Exception ex) {
ex.printStackTrace();
......@@ -146,106 +156,81 @@ public class Skin implements ActionListener{
}
}
}
/**
* Parses the given file line by line, expecting each xml-tag to be in his own single line
* @deprecated parseXML(File f) should now be used, as it is more flexible
* @param f The file that should be parsed
* @throws java.lang.Exception
*/
private void parse(File f) throws Exception {
//System.out.println("Creating Buffered Reader...");
BufferedReader br = new BufferedReader(new FileReader(f));
//System.out.println("Ready...");
//System.out.println("Reading Header...");
String header = br.readLine();
//System.out.println("Header read");
if (header.indexOf("//VideoLAN//DTD VLC Skins")==-1) {
br.close();
System.err.println("Invalid header:\n"+header);
throw new Exception(Language.get("ERROR_SKIN_INVALID"));
}
//System.out.println("Valid header");
boolean eof = false;
String line = "";
while(!eof) {
try {
//System.out.println("Reading line");
line = br.readLine();
if (line==null) break;
line = line.trim();
}
catch(Exception e) {
eof = true;
break;
}
if (line.startsWith("<!--")) {
while(line.indexOf("-->")==-1) {
line = br.readLine();
}
}
//<editor-fold defaultstate="collapsed" desc=" ThemeInfo tag ">
else if(line.startsWith("<ThemeInfo")) {
if(line.indexOf("name")!=-1) themeinfo_name = XML.getValue(line,"name");
if(line.indexOf("author")!=-1) themeinfo_author = XML.getValue(line,"author");
if(line.indexOf("email")!=-1) themeinfo_email = XML.getValue(line,"email");
if(line.indexOf("webpage")!=-1) themeinfo_webpage = XML.getValue(line,"webpage");
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc=" Theme tag ">
else if(line.startsWith("<Theme")) {
if(line.indexOf("version")!=-1) theme_version = XML.getValue(line,"version");
if(line.indexOf("tooltipfont")!=-1) theme_tooltipfont = XML.getValue(line,"tooltipfont");
if(line.indexOf("magnet")!=-1) theme_magnet = Integer.parseInt(XML.getValue(line,"magnet"));
if(line.indexOf(" alpha")!=-1) theme_alpha = Integer.parseInt(XML.getValue(line,"alpha"));
if(line.indexOf("movealpha")!=-1) theme_movealpha = Integer.parseInt(XML.getValue(line,"movealpha"));
//System.out.println("Creating Buffered Reader...");
BufferedReader br = new BufferedReader(new FileReader(f));
//System.out.println("Ready...");
//System.out.println("Reading Header...");
String header = br.readLine();
//System.out.println("Header read");
if (header.indexOf("//VideoLAN//DTD VLC Skins")==-1) {
br.close();
System.err.println("Invalid header:\n"+header);
throw new Exception(Language.get("ERROR_SKIN_INVALID"));
}
//System.out.println("Valid header");
boolean eof = false;
String line = "";
while(!eof) {
try {
//System.out.println("Reading line");
line = br.readLine();
if (line==null) break;
line = line.trim();
}
catch(Exception e) {
eof = true;
break;
}
if (line.startsWith("<!--")) {
while(line.indexOf("-->")==-1) {
line = br.readLine();
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc=" Bitmap tag ">
else if(line.startsWith("<Bitmap")) {
if(line.indexOf("/>")!=-1) {
resources.add(new Bitmap(line,this));
//System.out.println("Bitmap identified: "+line);
}
else {
//System.out.println("Bitmap with Subbitmaps identified: "+line);
boolean tagclosed=false;
String curline = "";
while(!tagclosed) {
try {
curline = br.readLine();
curline = curline.trim();
}
catch (Exception e) {
tagclosed=true;
}
if(curline.startsWith("</Bitmap>")) {
line +="\n"+curline;
tagclosed = true;
}
else {
line+="\n"+curline;
}
}
resources.add(new Bitmap(line,this));
//System.out.println("Bitmap with Subbmitmaps completely identified");
}
}
//<editor-fold defaultstate="collapsed" desc=" ThemeInfo tag ">
else if(line.startsWith("<ThemeInfo")) {
if(line.indexOf("name")!=-1) themeinfo_name = XML.getValue(line,"name");
if(line.indexOf("author")!=-1) themeinfo_author = XML.getValue(line,"author");
if(line.indexOf("email")!=-1) themeinfo_email = XML.getValue(line,"email");
if(line.indexOf("webpage")!=-1) themeinfo_webpage = XML.getValue(line,"webpage");
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc=" Theme tag ">
else if(line.startsWith("<Theme")) {
if(line.indexOf("version")!=-1) theme_version = XML.getValue(line,"version");
if(line.indexOf("tooltipfont")!=-1) theme_tooltipfont = XML.getValue(line,"tooltipfont");
if(line.indexOf("magnet")!=-1) theme_magnet = Integer.parseInt(XML.getValue(line,"magnet"));
if(line.indexOf(" alpha")!=-1) theme_alpha = Integer.parseInt(XML.getValue(line,"alpha"));
if(line.indexOf("movealpha")!=-1) theme_movealpha = Integer.parseInt(XML.getValue(line,"movealpha"));
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc=" Bitmap tag ">
else if(line.startsWith("<Bitmap")) {
if(line.indexOf("/>")!=-1) {
resources.add(new Bitmap(line,this));
//System.out.println("Bitmap identified: "+line);
}
//</editor-fold>
else if(line.startsWith("<Font")) resources.add(new Font(line,this));
else if(line.startsWith("<BitmapFont")) resources.add(new BitmapFont(line,this));
//<editor-fold defaultstate="collapsed" desc=" Window tag ">
else if(line.startsWith("<Window")) {
else {
//System.out.println("Bitmap with Subbitmaps identified: "+line);
boolean tagclosed=false;
String curline="";
String curline = "";
while(!tagclosed) {
try {
curline = br.readLine();
curline = curline.trim();
curline = curline.trim();
}
catch (Exception e) {
tagclosed=true;
}
if(curline.startsWith("</Window>")) {
if(curline.startsWith("</Bitmap>")) {
line +="\n"+curline;
tagclosed = true;
}
......@@ -253,59 +238,117 @@ public class Skin implements ActionListener{
line+="\n"+curline;
}
}
windows.add(new Window(line,this));
resources.add(new Bitmap(line,this));
//System.out.println("Bitmap with Subbmitmaps completely identified");
}
//</editor-fold>
}
br.close();
//System.out.println("Buffered Reader was closed");
//</editor-fold>
else if(line.startsWith("<Font")) resources.add(new Font(line,this));
else if(line.startsWith("<BitmapFont")) resources.add(new BitmapFont(line,this));
//<editor-fold defaultstate="collapsed" desc=" Window tag ">
else if(line.startsWith("<Window")) {
boolean tagclosed=false;
String curline="";
while(!tagclosed) {
try {
curline = br.readLine();
curline = curline.trim();
}
catch (Exception e) {
tagclosed=true;
}
if(curline.startsWith("</Window>")) {
line +="\n"+curline;
tagclosed = true;
}
else {
line+="\n"+curline;
}
}
windows.add(new Window(line,this));
}
//</editor-fold>
}
br.close();
//System.out.println("Buffered Reader was closed");
}
/**
* Parses the skin file via Java's XMLReader
* Parses the skin file using Java's built-in XML support
* @param f The file that should be parsed
* @throws java.lang.Exception
*/
private void parseXML(File f) throws Exception{
private void parseXML(File f) throws Exception{
//Workaround for DTD loading
File dtd = new File(f.getParent(),"skin.dtd");
if(!dtd.exists()) {
File included_dtd = new File("skin.dtd");
if(included_dtd.exists()) {
Helper.copyFile(included_dtd,dtd);
dtd.deleteOnExit();
}
}
//Now that the DTD is in the right place parse the XML
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setIgnoringComments(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(f);
if(!doc.getDoctype().getName().equals("Theme"))
throw new Exception(Language.get("ERROR_SKIN_INVALID"));
NodeList nodes = doc.getElementsByTagName("*");