Started implementation of generic XML config lists.

This commit is contained in:
StevenLawson 2014-08-27 14:13:52 -04:00
parent 334eafd7a0
commit 5ff5f765c3
5 changed files with 206 additions and 94 deletions

View file

@ -35,7 +35,7 @@ public class BTC_ConfigLoader
private static final String SETTINGS_FILE = "settings.xml"; private static final String SETTINGS_FILE = "settings.xml";
private final List<PlayerCommandEntry> playerCommands = new ArrayList<>(); private final List<PlayerCommandEntry> playerCommands = new ArrayList<>();
private final Set<ServerEntry> servers = new HashSet<>(); private final ServerEntry.ServerEntryList servers = new ServerEntry.ServerEntryList();
public BTC_ConfigLoader() public BTC_ConfigLoader()
{ {
@ -60,9 +60,6 @@ public class BTC_ConfigLoader
{ {
boolean loadError = loadXML(settings); boolean loadError = loadXML(settings);
final List<ServerEntry> oldServers = importOldConfig();
this.servers.addAll(oldServers);
generateXML(settings); generateXML(settings);
if (verbose) if (verbose)
@ -100,9 +97,9 @@ public class BTC_ConfigLoader
return this.playerCommands; return this.playerCommands;
} }
public Set<ServerEntry> getServers() public Collection<ServerEntry> getServers()
{ {
return servers; return this.servers.getList();
} }
private boolean generateXML(final File file) private boolean generateXML(final File file)
@ -115,7 +112,7 @@ public class BTC_ConfigLoader
doc.appendChild(rootElement); doc.appendChild(rootElement);
rootElement.appendChild(PlayerCommandEntry.listToXML(this.playerCommands, doc)); rootElement.appendChild(PlayerCommandEntry.listToXML(this.playerCommands, doc));
rootElement.appendChild(ServerEntry.listToXML(this.servers, doc)); rootElement.appendChild(this.servers.toXML(doc));
final Transformer transformer = TransformerFactory.newInstance().newTransformer(); final Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
@ -148,7 +145,7 @@ public class BTC_ConfigLoader
hadErrors = true; hadErrors = true;
} }
if (!ServerEntry.xmlToList(this.servers, doc)) if (!this.servers.fromXML(doc))
{ {
System.out.println("Error loading servers."); System.out.println("Error loading servers.");
hadErrors = true; hadErrors = true;
@ -183,34 +180,4 @@ public class BTC_ConfigLoader
return false; return false;
} }
private static List<ServerEntry> importOldConfig()
{
final List<ServerEntry> oldServers = new ArrayList<>();
try
{
final File file = new File("btc_servers.cfg");
if (file.exists())
{
try (final BufferedReader in = new BufferedReader(new FileReader(file)))
{
String line;
while ((line = in.readLine()) != null)
{
line = line.trim();
oldServers.add(new ServerEntry("legacy", line, false));
}
}
FileUtils.moveFile(file, new File("btc_servers.cfg.bak"));
}
}
catch (IOException ex)
{
BukkitTelnetClient.LOGGER.log(Level.SEVERE, null, ex);
}
return oldServers;
}
} }

View file

@ -157,7 +157,7 @@
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;ServerEntry&gt;"/> <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;me.StevenLawson.BukkitTelnetClient.ServerEntry&gt;"/>
</AuxValues> </AuxValues>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="chkAutoScroll"> <Component class="javax.swing.JCheckBox" name="chkAutoScroll">
@ -422,4 +422,4 @@
</SubComponents> </SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>
</Form> </Form>

View file

@ -0,0 +1,23 @@
/*
* Copyright (C) 2012-2014 Steven Lawson
*
* This file is part of BukkitTelnetClient.
*
* BukkitTelnetClient 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 me.StevenLawson.BukkitTelnetClient;
public interface ConfigEntry
{
}

View file

@ -0,0 +1,148 @@
/*
* Copyright (C) 2012-2014 Steven Lawson
*
* This file is part of BukkitTelnetClient.
*
* BukkitTelnetClient 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 me.StevenLawson.BukkitTelnetClient;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.logging.Level;
import org.w3c.dom.*;
public abstract class ConfigEntryList<E extends ConfigEntry>
{
private final Collection<E> list;
private final Class<E> entryClass;
public ConfigEntryList(Collection<E> list, Class<E> entryClass)
{
this.list = list;
this.entryClass = entryClass;
}
public Collection<E> getList()
{
return list;
}
public Class<E> getEntryClass()
{
return entryClass;
}
public Element toXML(final Document doc)
{
final Element parent = doc.createElement(getParentElementName());
for (final E entry : getList())
{
final Element item = doc.createElement(getItemElementName());
parent.appendChild(item);
for (final Method method : getEntryClass().getDeclaredMethods())
{
final ParameterGetter annotation = method.getDeclaredAnnotation(ParameterGetter.class);
if (annotation != null)
{
try
{
final Element parameter = doc.createElement(annotation.name());
parameter.appendChild(doc.createTextNode(method.invoke(entry).toString()));
item.appendChild(parameter);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | DOMException ex)
{
BukkitTelnetClient.LOGGER.log(Level.SEVERE, null, ex);
}
}
}
}
return parent;
}
public boolean fromXML(final Document doc)
{
NodeList itemNodes = doc.getDocumentElement().getElementsByTagName(getParentElementName());
if (itemNodes.getLength() < 1)
{
return false;
}
itemNodes.item(0).getChildNodes();
getList().clear();
for (int i = 0; i < itemNodes.getLength(); i++)
{
final Node node = itemNodes.item(0);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
final Element element = (Element) node;
try
{
final E newEntry = getEntryClass().newInstance();
for (final Method method : getEntryClass().getDeclaredMethods())
{
final ParameterSetter annotation = method.getDeclaredAnnotation(ParameterSetter.class);
if (annotation != null)
{
final String valueStr = element.getElementsByTagName(annotation.name()).item(0).getTextContent();
final Class<?> _type = method.getParameterTypes()[0];
if (_type == Boolean.class)
{
method.invoke(newEntry, Boolean.valueOf(valueStr));
}
else if (_type == String.class)
{
method.invoke(newEntry, valueStr);
}
}
}
getList().add(newEntry);
}
catch (Exception ex)
{
BukkitTelnetClient.LOGGER.log(Level.SEVERE, null, ex);
}
}
}
return true;
}
public abstract String getParentElementName();
public abstract String getItemElementName();
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ParameterGetter
{
public String name();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ParameterSetter
{
public String name();
}
}

View file

@ -18,15 +18,19 @@
*/ */
package me.StevenLawson.BukkitTelnetClient; package me.StevenLawson.BukkitTelnetClient;
import java.util.*; import java.util.HashSet;
import org.w3c.dom.*; import java.util.Objects;
public class ServerEntry public class ServerEntry implements ConfigEntry
{ {
private String name; private String name;
private String address; private String address;
private boolean lastUsed = false; private boolean lastUsed = false;
public ServerEntry()
{
}
public ServerEntry(final String name, final String address) public ServerEntry(final String name, final String address)
{ {
this.name = name; this.name = name;
@ -40,32 +44,38 @@ public class ServerEntry
this.lastUsed = lastUsed; this.lastUsed = lastUsed;
} }
@ConfigEntryList.ParameterGetter(name = "name")
public String getName() public String getName()
{ {
return name; return name;
} }
@ConfigEntryList.ParameterSetter(name = "name")
public void setName(String name) public void setName(String name)
{ {
this.name = name; this.name = name;
} }
@ConfigEntryList.ParameterGetter(name = "address")
public String getAddress() public String getAddress()
{ {
return address; return address;
} }
@ConfigEntryList.ParameterSetter(name = "address")
public void setAddress(String address) public void setAddress(String address)
{ {
this.address = address; this.address = address;
} }
@ConfigEntryList.ParameterGetter(name = "lastUsed")
public boolean isLastUsed() public boolean isLastUsed()
{ {
return lastUsed; return lastUsed;
} }
public void setLastUsed(boolean lastUsed) @ConfigEntryList.ParameterSetter(name = "lastUsed")
public void setLastUsed(Boolean lastUsed)
{ {
this.lastUsed = lastUsed; this.lastUsed = lastUsed;
} }
@ -74,8 +84,8 @@ public class ServerEntry
public int hashCode() public int hashCode()
{ {
int hash = 7; int hash = 7;
hash = 67 * hash + Objects.hashCode(this.name); hash = 59 * hash + Objects.hashCode(this.name);
hash = 67 * hash + Objects.hashCode(this.address); hash = 59 * hash + Objects.hashCode(this.address);
return hash; return hash;
} }
@ -107,65 +117,29 @@ public class ServerEntry
return true; return true;
} }
public static Element listToXML(final Set<ServerEntry> servers, final Document doc) public static class ServerEntryList extends ConfigEntryList<ServerEntry>
{ {
final Element serversElement = doc.createElement("servers"); public ServerEntryList()
for (final ServerEntry command : servers)
{ {
final Element commandElement = doc.createElement("server"); super(new HashSet<ServerEntry>(), ServerEntry.class);
serversElement.appendChild(commandElement);
final Element serverName = doc.createElement("name");
serverName.appendChild(doc.createTextNode(command.getName()));
commandElement.appendChild(serverName);
final Element serverAddress = doc.createElement("address");
serverAddress.appendChild(doc.createTextNode(command.getAddress()));
commandElement.appendChild(serverAddress);
final Element serverLastUsed = doc.createElement("lastUsed");
serverLastUsed.appendChild(doc.createTextNode(Boolean.toString(command.isLastUsed())));
commandElement.appendChild(serverLastUsed);
} }
return serversElement; @Override
} public String getParentElementName()
public static boolean xmlToList(final Set<ServerEntry> servers, final Document doc)
{
NodeList serverNodes = doc.getDocumentElement().getElementsByTagName("servers");
if (serverNodes.getLength() < 1)
{ {
return false; return "servers";
}
serverNodes = serverNodes.item(0).getChildNodes();
servers.clear();
for (int i = 0; i < serverNodes.getLength(); i++)
{
final Node node = serverNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
final Element element = (Element) node;
final ServerEntry server = new ServerEntry(
element.getElementsByTagName("name").item(0).getTextContent(),
element.getElementsByTagName("address").item(0).getTextContent(),
Boolean.valueOf(element.getElementsByTagName("lastUsed").item(0).getTextContent())
);
servers.add(server);
}
} }
return true; @Override
public String getItemElementName()
{
return "server";
}
} }
@Override @Override
public String toString() public String toString()
{ {
return String.format("%s (%s)", this.name, this.address); return String.format("%s (%s)", getName(), getAddress());
} }
} }