diff --git a/config/config.xml b/config/config.xml
new file mode 100644
index 000000000..6397b0c4f
--- /dev/null
+++ b/config/config.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ 1.0
+
+ 1.0
+
+
+
+
+
+
+
+
+
+ jdbc:mysql://localhost/l2jserver2
+
+
+ com.mysql.jdbc.Driver
+
+
+ l2j
+
+
+ changeme
+
+
+
+
+ 20
+
+ 20
+
+ 5
+
+
+
+
+
+
+ 0.0.0.0:7777
+
+
+
+
+
+
+
+
+
+
+ data/templates
+
+
+
+
\ No newline at end of file
diff --git a/config/database.properties b/config/properties/database.properties
similarity index 100%
rename from config/database.properties
rename to config/properties/database.properties
diff --git a/config/template.properties b/config/properties/template.properties
similarity index 100%
rename from config/template.properties
rename to config/properties/template.properties
diff --git a/config/vfs.properties b/config/properties/vfs.properties
similarity index 100%
rename from config/vfs.properties
rename to config/properties/vfs.properties
diff --git a/dist/config/config.xml b/dist/config/config.xml
new file mode 100644
index 000000000..6397b0c4f
--- /dev/null
+++ b/dist/config/config.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ 1.0
+
+ 1.0
+
+
+
+
+
+
+
+
+
+ jdbc:mysql://localhost/l2jserver2
+
+
+ com.mysql.jdbc.Driver
+
+
+ l2j
+
+
+ changeme
+
+
+
+
+ 20
+
+ 20
+
+ 5
+
+
+
+
+
+
+ 0.0.0.0:7777
+
+
+
+
+
+
+
+
+
+
+ data/templates
+
+
+
+
\ No newline at end of file
diff --git a/dist/config/database.properties b/dist/config/properties/database.properties
similarity index 100%
rename from dist/config/database.properties
rename to dist/config/properties/database.properties
diff --git a/dist/config/template.properties b/dist/config/properties/template.properties
similarity index 100%
rename from dist/config/template.properties
rename to dist/config/properties/template.properties
diff --git a/dist/config/vfs.properties b/dist/config/properties/vfs.properties
similarity index 100%
rename from dist/config/vfs.properties
rename to dist/config/properties/vfs.properties
diff --git a/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java b/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java
index 801108e4c..7b90a797e 100644
--- a/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java
+++ b/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java
@@ -124,7 +124,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
body.text(exception);
}
};
- connection.sendCommunityHTML(template);
+ connection.sendHTML(template);
// order client not to wait any packet
connection.sendActionFailed();
diff --git a/src/main/java/com/l2jserver/service/configuration/Configuration.java b/src/main/java/com/l2jserver/service/configuration/Configuration.java
index 819d1d56b..d651f3911 100644
--- a/src/main/java/com/l2jserver/service/configuration/Configuration.java
+++ b/src/main/java/com/l2jserver/service/configuration/Configuration.java
@@ -16,12 +16,13 @@
*/
package com.l2jserver.service.configuration;
-import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
+
/**
* Configuration interface
*
@@ -35,23 +36,6 @@ import java.lang.annotation.Target;
* @author Rogiel
*/
public interface Configuration {
- /**
- * Each configuration can define the name of its configuration. This will be
- * used by implementations to look for the configuration.
- *
- * @author Rogiel
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Target(value = ElementType.TYPE)
- public @interface ConfigurationName {
- /**
- * @return the configuration name
- */
- String value();
- }
-
/**
* The getter method for an configuration property
*
@@ -62,11 +46,6 @@ public interface Configuration {
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface ConfigurationPropertyGetter {
- /**
- * @return the property name
- */
- String name();
-
/**
* @return the default value to be used
*/
@@ -83,9 +62,5 @@ public interface Configuration {
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface ConfigurationPropertySetter {
- /**
- * @return the property name
- */
- String name();
}
}
diff --git a/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java b/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java
index 1cc1bba3b..417ffc692 100644
--- a/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java
+++ b/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java
@@ -21,6 +21,11 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -35,7 +40,6 @@ import com.l2jserver.service.AbstractService;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.cache.CacheService;
-import com.l2jserver.service.configuration.Configuration.ConfigurationName;
import com.l2jserver.service.configuration.Configuration.ConfigurationPropertyGetter;
import com.l2jserver.service.configuration.Configuration.ConfigurationPropertySetter;
import com.l2jserver.service.core.LoggingService;
@@ -55,7 +59,7 @@ public class ProxyConfigurationService extends AbstractService implements
/**
* The directory in which configuration files are stored
*/
- private final File directory = new File("./config");
+ private final File directory = new File("./config/properties");
/**
* The logger
*/
@@ -66,6 +70,30 @@ public class ProxyConfigurationService extends AbstractService implements
*/
private Map, Object> cache = CollectionFactory.newWeakMap();
+ @Retention(RetentionPolicy.RUNTIME)
+ @Documented
+ @Target(value = ElementType.METHOD)
+ public @interface ConfigurationPropertiesKey {
+ String value();
+ }
+
+ /**
+ * Each configuration can define the name of its configuration. This will be
+ * used by implementations to look for the configuration.
+ *
+ * @author Rogiel
+ *
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Documented
+ @Target(value = ElementType.TYPE)
+ public @interface ConfigurationName {
+ /**
+ * @return the configuration name
+ */
+ String value();
+ }
+
@Override
protected void doStart() throws ServiceStartException {
if (!directory.exists())
@@ -128,15 +156,23 @@ public class ProxyConfigurationService extends AbstractService implements
if (args == null || args.length == 0) {
final ConfigurationPropertyGetter getter = method
.getAnnotation(ConfigurationPropertyGetter.class);
+ final ConfigurationPropertiesKey propertiesKey = method
+ .getAnnotation(ConfigurationPropertiesKey.class);
if (getter == null)
return null;
- return get(getter, method.getReturnType());
+ if (propertiesKey == null)
+ return null;
+ return get(getter, propertiesKey, method.getReturnType());
} else if (args.length == 1) {
final ConfigurationPropertySetter setter = method
.getAnnotation(ConfigurationPropertySetter.class);
+ final ConfigurationPropertiesKey propertiesKey = method
+ .getAnnotation(ConfigurationPropertiesKey.class);
if (setter == null)
return null;
- set(setter, args[0], method.getParameterTypes()[0]);
+ if (propertiesKey == null)
+ return null;
+ set(propertiesKey, args[0], method.getParameterTypes()[0]);
}
return null;
}
@@ -146,16 +182,19 @@ public class ProxyConfigurationService extends AbstractService implements
*
* @param getter
* the getter annotation
+ * @param propertiesKey
+ * if properties key annotation
* @param type
* the transformed type
* @return the untransformed property
*/
- private Object get(ConfigurationPropertyGetter getter, Class> type) {
- if (cache.containsKey(getter.name()))
- return cache.get(getter.name());
+ private Object get(ConfigurationPropertyGetter getter,
+ ConfigurationPropertiesKey propertiesKey, Class> type) {
+ if (cache.containsKey(propertiesKey.value()))
+ return cache.get(propertiesKey.value());
Object o = untransform(
- getRaw(getter.name(), getter.defaultValue()), type);
- cache.put(getter.name(), o);
+ getRaw(propertiesKey.value(), getter.defaultValue()), type);
+ cache.put(propertiesKey.value(), o);
return o;
}
@@ -169,15 +208,15 @@ public class ProxyConfigurationService extends AbstractService implements
* @param type
* the transformed type
*/
- private void set(ConfigurationPropertySetter setter, Object value,
+ private void set(ConfigurationPropertiesKey setter, Object value,
Class> type) {
if (value != null) {
- properties.setProperty(setter.name(),
+ properties.setProperty(setter.value(),
transform(value.toString(), type));
- cache.remove(setter.name());
+ cache.remove(setter.value());
} else {
- properties.remove(setter.name());
- cache.remove(setter.name());
+ properties.remove(setter.value());
+ cache.remove(setter.value());
}
}
diff --git a/src/main/java/com/l2jserver/service/configuration/XMLConfigurationService.java b/src/main/java/com/l2jserver/service/configuration/XMLConfigurationService.java
new file mode 100644
index 000000000..75027aa8b
--- /dev/null
+++ b/src/main/java/com/l2jserver/service/configuration/XMLConfigurationService.java
@@ -0,0 +1,343 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.service.configuration;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import com.google.common.base.Preconditions;
+import com.google.inject.Inject;
+import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.AbstractService.Depends;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.cache.CacheService;
+import com.l2jserver.service.configuration.Configuration.ConfigurationPropertyGetter;
+import com.l2jserver.service.core.LoggingService;
+import com.l2jserver.util.factory.CollectionFactory;
+import com.l2jserver.util.transformer.Transformer;
+import com.l2jserver.util.transformer.TransformerFactory;
+
+/**
+ * Creates {@link Configuration} object through Java {@link Proxy}. Uses the
+ * annotations in the interface to retrieve and store values.
+ *
+ * @author Rogiel
+ */
+@Depends({ LoggingService.class, CacheService.class })
+public class XMLConfigurationService extends AbstractService implements
+ ConfigurationService {
+ /**
+ * The directory in which configuration files are stored
+ */
+ private File file = new File("./config/config.xml");
+ /**
+ * The logger
+ */
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ /**
+ * The DOM {@link DocumentBuilderFactory}
+ */
+ private DocumentBuilderFactory factory;
+ /**
+ * The DOM {@link DocumentBuilder}
+ */
+ private DocumentBuilder builder;
+
+ private Document properties;
+
+ /**
+ * The cache of configuration objects
+ */
+ private Map, Object> cache = CollectionFactory.newWeakMap();
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ConfigurationXPath {
+ String value();
+ }
+
+ /**
+ * Creates a new empty instance
+ */
+ @Inject
+ protected XMLConfigurationService() {
+ }
+
+ /**
+ * Creates a new service instance. This is used for tests
+ *
+ * @param file
+ * the configuration file
+ */
+ protected XMLConfigurationService(File file) {
+ this.file = file;
+ }
+
+ @Override
+ protected void doStart() throws ServiceStartException {
+ factory = DocumentBuilderFactory.newInstance();
+ try {
+ builder = factory.newDocumentBuilder();
+ properties = builder.parse(file);
+ } catch (ParserConfigurationException e) {
+ throw new ServiceStartException(e);
+ } catch (SAXException e) {
+ throw new ServiceStartException(e);
+ } catch (IOException e) {
+ throw new ServiceStartException(e);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public C get(Class config) {
+ Preconditions.checkNotNull(config, "config");
+
+ if (cache.containsKey(config))
+ return (C) cache.get(config);
+ log.debug("Trying to create {} proxy", config);
+
+ C proxy = (C) Proxy.newProxyInstance(this.getClass().getClassLoader(),
+ new Class>[] { config }, new ConfigInvocationHandler(
+ properties));
+ cache.put(config, proxy);
+ return proxy;
+ }
+
+ /**
+ * The invocation handler for configuration interfaces
+ *
+ * @author Rogiel
+ */
+ private class ConfigInvocationHandler implements InvocationHandler {
+ /**
+ * The invocation handler properties
+ */
+ private final Document properties;
+ /**
+ * The invocation cache
+ */
+ private Map cache = CollectionFactory.newWeakMap();
+
+ /**
+ * @param properties
+ * the properties
+ */
+ public ConfigInvocationHandler(Document properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ log.debug("Configuration service, method invoked: {}",
+ method.getName());
+ if (args == null || args.length == 0) {
+ final ConfigurationPropertyGetter getter = method
+ .getAnnotation(ConfigurationPropertyGetter.class);
+ final ConfigurationXPath xpath = method
+ .getAnnotation(ConfigurationXPath.class);
+ if (getter == null)
+ return null;
+ if (xpath == null)
+ return null;
+ return get(getter, xpath, method.getReturnType());
+ } else if (args.length == 1) {
+ final ConfigurationXPath xpath = method
+ .getAnnotation(ConfigurationXPath.class);
+ if (xpath == null)
+ return null;
+ set(xpath, args[0], method.getParameterTypes()[0]);
+ }
+ return null;
+ }
+
+ /**
+ * Get the untransformed value of an property
+ *
+ * @param getter
+ * the getter annotation
+ * @param xpath
+ * the xpath annotation
+ * @param type
+ * the transformed type
+ * @return the untransformed property
+ */
+ private Object get(ConfigurationPropertyGetter getter,
+ ConfigurationXPath xpath, Class> type) {
+ if (cache.containsKey(xpath.value()))
+ return cache.get(xpath.value());
+ Object o;
+ try {
+ o = untransform(getRaw(xpath.value(), getter.defaultValue()),
+ type);
+ } catch (XPathExpressionException e) {
+ return null;
+ }
+ cache.put(xpath.value(), o);
+ return o;
+ }
+
+ /**
+ * Set the transformed value of an property
+ *
+ * @param xpath
+ * the xpath annotation
+ * @param value
+ * the untransformed value
+ * @param type
+ * the transformed type
+ * @throws XPathExpressionException
+ * if any error occur while compiling the XPath
+ */
+ private void set(ConfigurationXPath xpath, Object value, Class> type)
+ throws XPathExpressionException {
+ Node node = (Node) XPathFactory.newInstance().newXPath()
+ .compile(xpath.value())
+ .evaluate(properties, XPathConstants.NODE);
+ if (value != null) {
+ node.setNodeValue(transform(value.toString(), type));
+ cache.put(xpath.value(), value);
+ } else {
+ node.getParentNode().removeChild(node);
+ cache.remove(xpath.value());
+ }
+ }
+
+ /**
+ * Untransforms an value
+ *
+ * @param value
+ * the raw value
+ * @param type
+ * the output type
+ * @return the untransformed value
+ */
+ private Object untransform(String value, Class> type) {
+ if (value == null)
+ return null;
+ if (type == String.class)
+ return value;
+ final Transformer> transformer = TransformerFactory
+ .getTransfromer(type);
+ if (transformer == null)
+ return null;
+ return transformer.untransform(value);
+ }
+
+ /**
+ * Transforms an value
+ *
+ * @param value
+ * the raw typed value
+ * @param type
+ * the input type
+ * @return the string representing value
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private String transform(Object value, Class> type) {
+ if (value == null)
+ return null;
+ if (value instanceof String)
+ return (String) value;
+ final Transformer transformer = TransformerFactory
+ .getTransfromer(type);
+ if (transformer == null)
+ return null;
+ return transformer.transform(value);
+ }
+
+ /**
+ * Retrieve the raw value from the property file
+ *
+ * @param key
+ * the key
+ * @param defaultValue
+ * the default value
+ * @return the value found or default value
+ * @throws XPathExpressionException
+ * if any XPath exception occur
+ */
+ private String getRaw(String key, String defaultValue)
+ throws XPathExpressionException {
+ if (properties == null)
+ return defaultValue;
+ String value = XPathFactory.newInstance().newXPath()
+ .evaluate(key, properties);
+ if (value == null || value.length() == 0)
+ return defaultValue;
+ return value;
+ }
+ }
+
+ /**
+ * Tries to find an annotation in the class or any parent-class.
+ *
+ * @param
+ * the annotation type
+ * @param annotationClass
+ * the annotation class
+ * @param clazz
+ * the class to look for annotations
+ * @return the annotation found
+ */
+ private T findAnnotation(Class annotationClass,
+ Class> clazz) {
+ Preconditions.checkNotNull(annotationClass, "annotationClass");
+ Preconditions.checkNotNull(clazz, "clazz");
+
+ T ann = clazz.getAnnotation(annotationClass);
+ if (ann != null)
+ return ann;
+
+ for (Class> clazz2 : annotationClass.getInterfaces()) {
+ if (clazz2 == clazz)
+ continue;
+ ann = findAnnotation(annotationClass, clazz2);
+ if (ann != null)
+ return ann;
+ }
+ return null;
+ }
+
+ /**
+ * @return the configuration store directory
+ */
+ public File getFile() {
+ return file;
+ }
+}
diff --git a/src/main/java/com/l2jserver/service/core/vfs/VFSService.java b/src/main/java/com/l2jserver/service/core/vfs/VFSService.java
index b29211abd..fedcf162b 100644
--- a/src/main/java/com/l2jserver/service/core/vfs/VFSService.java
+++ b/src/main/java/com/l2jserver/service/core/vfs/VFSService.java
@@ -22,7 +22,9 @@ import java.nio.file.Path;
import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration;
-import com.l2jserver.service.configuration.Configuration.ConfigurationName;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertiesKey;
+import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
/**
* The VFS service is responsible for creating a Virtual File System that is
@@ -42,14 +44,18 @@ public interface VFSService extends Service {
/**
* @return the VFS root {@link URI}
*/
- @ConfigurationPropertyGetter(name = "vfs.root", defaultValue = "")
+ @ConfigurationPropertyGetter(defaultValue = "")
+ @ConfigurationPropertiesKey("vfs.root")
+ @ConfigurationXPath("/configuration/services/vfs/root")
Path getRoot();
/**
* @param root
* the new VFS root {@link URI}
*/
- @ConfigurationPropertySetter(name = "vfs.root")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("vfs.root")
+ @ConfigurationXPath("/configuration/services/vfs/root")
void setRoot(Path root);
}
diff --git a/src/main/java/com/l2jserver/service/database/DatabaseService.java b/src/main/java/com/l2jserver/service/database/DatabaseService.java
index f0522c412..d04698857 100644
--- a/src/main/java/com/l2jserver/service/database/DatabaseService.java
+++ b/src/main/java/com/l2jserver/service/database/DatabaseService.java
@@ -21,7 +21,7 @@ import com.l2jserver.model.id.ID;
import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration;
-import com.l2jserver.service.configuration.Configuration.ConfigurationName;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
/**
* This service provides access to an database implementation. Each
diff --git a/src/main/java/com/l2jserver/service/database/JDBCDatabaseService.java b/src/main/java/com/l2jserver/service/database/JDBCDatabaseService.java
index e3e26f2c8..59889a55e 100644
--- a/src/main/java/com/l2jserver/service/database/JDBCDatabaseService.java
+++ b/src/main/java/com/l2jserver/service/database/JDBCDatabaseService.java
@@ -60,6 +60,8 @@ import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.cache.Cache;
import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertiesKey;
+import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
import com.l2jserver.service.core.threading.ThreadService;
@@ -155,92 +157,120 @@ public class JDBCDatabaseService extends AbstractService implements
/**
* @return the jdbc url
*/
- @ConfigurationPropertyGetter(name = "jdbc.url", defaultValue = "jdbc:mysql://localhost/l2jserver2")
+ @ConfigurationPropertyGetter(defaultValue = "jdbc:mysql://localhost/l2jserver2")
+ @ConfigurationPropertiesKey("jdbc.url")
+ @ConfigurationXPath("/configuration/services/database/jdbc/url")
String getJdbcUrl();
/**
* @param jdbcUrl
* the new jdbc url
*/
- @ConfigurationPropertySetter(name = "jdbc.url")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.url")
+ @ConfigurationXPath("/configuration/services/database/jdbc/url")
void setJdbcUrl(String jdbcUrl);
/**
* @return the jdbc driver class
*/
- @ConfigurationPropertyGetter(name = "jdbc.driver", defaultValue = "com.jdbc.jdbc.Driver")
+ @ConfigurationPropertyGetter(defaultValue = "com.jdbc.jdbc.Driver")
+ @ConfigurationPropertiesKey("jdbc.driver")
+ @ConfigurationXPath("/configuration/services/database/jdbc/driver")
String getDriver();
/**
* @param driver
* the new jdbc driver
*/
- @ConfigurationPropertySetter(name = "jdbc.driver")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.driver")
+ @ConfigurationXPath("/configuration/services/database/jdbc/driver")
void setDriver(Class> driver);
/**
* @return the jdbc database username
*/
- @ConfigurationPropertyGetter(name = "jdbc.username", defaultValue = "l2j")
+ @ConfigurationPropertyGetter(defaultValue = "l2j")
+ @ConfigurationPropertiesKey("jdbc.username")
+ @ConfigurationXPath("/configuration/services/database/jdbc/username")
String getUsername();
/**
* @param username
* the jdbc database username
*/
- @ConfigurationPropertySetter(name = "jdbc.username")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.username")
+ @ConfigurationXPath("/configuration/services/database/jdbc/username")
void setUsername(String username);
/**
* @return the jdbc database password
*/
- @ConfigurationPropertyGetter(name = "jdbc.password", defaultValue = "changeme")
+ @ConfigurationPropertyGetter(defaultValue = "changeme")
+ @ConfigurationPropertiesKey("jdbc.password")
+ @ConfigurationXPath("/configuration/services/database/jdbc/password")
String getPassword();
/**
* @param password
* the jdbc database password
*/
- @ConfigurationPropertySetter(name = "jdbc.password")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.password")
+ @ConfigurationXPath("/configuration/services/database/jdbc/password")
void setPassword(String password);
/**
* @return the maximum number of active connections
*/
- @ConfigurationPropertyGetter(name = "jdbc.active.max", defaultValue = "20")
+ @ConfigurationPropertyGetter(defaultValue = "20")
+ @ConfigurationPropertiesKey("jdbc.active.max")
+ @ConfigurationXPath("/configuration/services/database/connections/active-maximum")
int getMaxActiveConnections();
/**
* @param password
* the maximum number of active connections
*/
- @ConfigurationPropertySetter(name = "jdbc.active.max")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.active.max")
+ @ConfigurationXPath("/configuration/services/database/connections/active-maximum")
void setMaxActiveConnections(int password);
/**
* @return the maximum number of idle connections
*/
- @ConfigurationPropertyGetter(name = "jdbc.idle.max", defaultValue = "20")
+ @ConfigurationPropertyGetter(defaultValue = "20")
+ @ConfigurationPropertiesKey("jdbc.idle.max")
+ @ConfigurationXPath("/configuration/services/database/connections/idle-maximum")
int getMaxIdleConnections();
/**
* @param password
* the maximum number of idle connections
*/
- @ConfigurationPropertySetter(name = "jdbc.idle.max")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.idle.max")
+ @ConfigurationXPath("/configuration/services/database/connections/idle-maximum")
void setMaxIdleConnections(int password);
/**
* @return the minimum number of idle connections
*/
- @ConfigurationPropertyGetter(name = "jdbc.idle.min", defaultValue = "5")
+ @ConfigurationPropertyGetter(defaultValue = "5")
+ @ConfigurationPropertiesKey("jdbc.idle.min")
+ @ConfigurationXPath("/configuration/services/database/connections/idle-minimum")
int getMinIdleConnections();
/**
* @param password
* the minimum number of idle connections
*/
- @ConfigurationPropertySetter(name = "jdbc.idle.min")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("jdbc.idle.min")
+ @ConfigurationXPath("/configuration/services/database/connections/idle-minimum")
void setMinIdleConnections(int password);
}
diff --git a/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java b/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java
index f8d1f0ae6..35e0d87d1 100644
--- a/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java
+++ b/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java
@@ -54,8 +54,10 @@ import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.cache.Cache;
import com.l2jserver.service.cache.CacheService;
-import com.l2jserver.service.configuration.Configuration.ConfigurationName;
import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertiesKey;
+import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.vfs.VFSService;
import com.l2jserver.util.jaxb.CharacterTemplateIDAdapter;
@@ -139,14 +141,18 @@ public class XMLTemplateService extends AbstractService implements
/**
* @return the directory in which templates are stored
*/
- @ConfigurationPropertyGetter(name = "template.directory", defaultValue = "data/templates")
+ @ConfigurationPropertyGetter(defaultValue = "data/templates")
+ @ConfigurationPropertiesKey("template.directory")
+ @ConfigurationXPath("/configuration/services/template/directory")
URI getTemplateDirectory();
/**
* @param file
* the directory in which templates are stored
*/
- @ConfigurationPropertySetter(name = "template.directory")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("template.directory")
+ @ConfigurationXPath("/configuration/services/template/directory")
void setTemplateDirectory(URI file);
}
diff --git a/src/main/java/com/l2jserver/service/network/NetworkService.java b/src/main/java/com/l2jserver/service/network/NetworkService.java
index c187857e3..a8760da12 100644
--- a/src/main/java/com/l2jserver/service/network/NetworkService.java
+++ b/src/main/java/com/l2jserver/service/network/NetworkService.java
@@ -27,7 +27,9 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration;
-import com.l2jserver.service.configuration.Configuration.ConfigurationName;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
+import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertiesKey;
+import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
/**
* The network service is responsible for communicating the server with the game
@@ -78,7 +80,9 @@ public interface NetworkService extends Service {
*
* @return the listen address
*/
- @ConfigurationPropertyGetter(name = "listen", defaultValue = "0.0.0.0:7777")
+ @ConfigurationPropertyGetter(defaultValue = "0.0.0.0:7777")
+ @ConfigurationPropertiesKey("network.listen")
+ @ConfigurationXPath("/configuration/services/network/listen")
InetSocketAddress getListenAddress();
/**
@@ -87,7 +91,9 @@ public interface NetworkService extends Service {
* @param addr
* the listen address
*/
- @ConfigurationPropertySetter(name = "listen")
+ @ConfigurationPropertySetter
+ @ConfigurationPropertiesKey("network.listen")
+ @ConfigurationXPath("/configuration/services/network/listen")
void setListenAddress(InetSocketAddress addr);
}
diff --git a/src/test/java/com/l2jserver/service/configuration/XMLConfigurationServiceTest.java b/src/test/java/com/l2jserver/service/configuration/XMLConfigurationServiceTest.java
new file mode 100644
index 000000000..fe8e4a61b
--- /dev/null
+++ b/src/test/java/com/l2jserver/service/configuration/XMLConfigurationServiceTest.java
@@ -0,0 +1,100 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.service.configuration;
+
+import java.io.File;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
+
+/**
+ * @author Rogiel
+ *
+ */
+public class XMLConfigurationServiceTest {
+ /**
+ * The {@link TestConfig} proxy
+ */
+ private TestConfig config;
+
+ @Before
+ public void tearUp() throws ServiceStartException {
+ final XMLConfigurationService service = new XMLConfigurationService(
+ new File("src/test/resources/test-config.xml"));
+ service.start();
+ config = service.get(TestConfig.class);
+ }
+
+ @Test
+ public void testString() throws ServiceStartException {
+ Assert.assertEquals("test", config.getTestString());
+ }
+
+ @Test
+ public void testDefaultValue() throws ServiceStartException {
+ Assert.assertEquals("default", config.getDefaultTestString());
+ }
+
+ @Test
+ public void testInteger() throws ServiceStartException {
+ Assert.assertEquals(256, config.getTestInteger());
+ }
+
+ @Test
+ public void testSetter() throws ServiceStartException {
+ config.setTestString("new-value");
+ Assert.assertEquals("new-value", config.getTestString());
+ }
+
+ @Test
+ public void testNullSetter() throws ServiceStartException {
+ config.setTestString(null);
+ Assert.assertEquals("test-default", config.getTestString());
+ }
+
+ /**
+ * The TestConfig interface
+ *
+ * @author Rogiel
+ */
+ public interface TestConfig extends Configuration {
+ @ConfigurationPropertyGetter(defaultValue = "test-default")
+ @ConfigurationXPath("/configuration/test/testvalue")
+ String getTestString();
+
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/test/testvalue")
+ void setTestString(String value);
+
+ @ConfigurationPropertyGetter(defaultValue = "default")
+ @ConfigurationXPath("/configuration/test/nonexistentkey")
+ String getDefaultTestString();
+
+ @ConfigurationPropertyGetter(defaultValue = "0")
+ @ConfigurationXPath("/configuration/test/integer")
+ int getTestInteger();
+
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/test/integer")
+ void setTestInteger(Integer n);
+ }
+}
diff --git a/src/test/resources/test-config.xml b/src/test/resources/test-config.xml
new file mode 100644
index 000000000..fb4d3e840
--- /dev/null
+++ b/src/test/resources/test-config.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ test
+ 256
+
+
\ No newline at end of file