mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-09 08:52:51 +00:00
Removed "core" project dependency
Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
17
src/main/java/com/l2jserver/service/AbstractService.java
Normal file
17
src/main/java/com/l2jserver/service/AbstractService.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
public class AbstractService implements Service {
|
||||
@Override
|
||||
public void start() throws ServiceStartException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws ServiceStopException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restart() throws ServiceException {
|
||||
this.stop();
|
||||
this.start();
|
||||
}
|
||||
}
|
||||
27
src/main/java/com/l2jserver/service/Service.java
Normal file
27
src/main/java/com/l2jserver/service/Service.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
public interface Service {
|
||||
/**
|
||||
* Start this service
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
* if an error occurred
|
||||
*/
|
||||
void start() throws ServiceStartException;
|
||||
|
||||
/**
|
||||
* Stop this service
|
||||
*
|
||||
* @throws ServiceStopException
|
||||
* if an error occurred
|
||||
*/
|
||||
void stop() throws ServiceStopException;
|
||||
|
||||
/**
|
||||
* Stop this service
|
||||
*
|
||||
* @throws ServiceException
|
||||
* if an error occurred
|
||||
*/
|
||||
void restart() throws ServiceException;
|
||||
}
|
||||
21
src/main/java/com/l2jserver/service/ServiceException.java
Normal file
21
src/main/java/com/l2jserver/service/ServiceException.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
public class ServiceException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServiceException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ServiceException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ServiceException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
93
src/main/java/com/l2jserver/service/ServiceManager.java
Normal file
93
src/main/java/com/l2jserver/service/ServiceManager.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.l2jserver.service.logging.LoggingService;
|
||||
|
||||
public class ServiceManager {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private final Logger logger;
|
||||
/**
|
||||
* The Guice Injector
|
||||
*/
|
||||
private final Injector injector;
|
||||
|
||||
@Inject
|
||||
public ServiceManager(Injector injector) {
|
||||
this.injector = injector;
|
||||
final LoggingService service = injector
|
||||
.getInstance(LoggingService.class);
|
||||
try {
|
||||
service.start();
|
||||
} catch (ServiceStartException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
logger = LoggerFactory.getLogger(ServiceManager.class);
|
||||
}
|
||||
|
||||
public <T extends Service> T start(Class<T> serviceClass)
|
||||
throws ServiceStartException {
|
||||
final T service = injector.getInstance(serviceClass);
|
||||
if (service == null)
|
||||
return null;
|
||||
try {
|
||||
logger.info("{}: Starting service...",
|
||||
serviceClass.getCanonicalName());
|
||||
service.start();
|
||||
logger.info("{}: Service started!",
|
||||
serviceClass.getCanonicalName());
|
||||
return service;
|
||||
} catch (ServiceStartException e) {
|
||||
logger.error("{}: Error starting service: {}",
|
||||
serviceClass.getCanonicalName(), e.getCause());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(Class<? extends Service> serviceClass)
|
||||
throws ServiceStopException {
|
||||
final Service service = injector.getInstance(serviceClass);
|
||||
if (service == null)
|
||||
return;
|
||||
try {
|
||||
logger.info("{0}: Stopping service...",
|
||||
serviceClass.getCanonicalName());
|
||||
service.stop();
|
||||
logger.info("{0}: Service stopped!",
|
||||
serviceClass.getCanonicalName());
|
||||
} catch (ServiceStopException e) {
|
||||
logger.error("{0}: Error stopping service: {1}",
|
||||
serviceClass.getCanonicalName(), e.getCause());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Service> T restart(Class<T> serviceClass)
|
||||
throws ServiceStartException, ServiceStopException {
|
||||
final T service = injector.getInstance(serviceClass);
|
||||
if (service == null)
|
||||
return null;
|
||||
try {
|
||||
logger.info("{0}: Restaring service...",
|
||||
serviceClass.getCanonicalName());
|
||||
service.stop();
|
||||
service.start();
|
||||
logger.info("{0}: Service restarted!",
|
||||
serviceClass.getCanonicalName());
|
||||
return service;
|
||||
} catch (ServiceStartException e) {
|
||||
logger.error("{0}: Error starting service: {1}",
|
||||
serviceClass.getCanonicalName(), e.getCause());
|
||||
throw e;
|
||||
} catch (ServiceStopException e) {
|
||||
logger.error("{0}: Error stopping service: {1}",
|
||||
serviceClass.getCanonicalName(), e.getCause());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package com.l2jserver.service;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.configuration.ProxyConfigurationService;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
import com.l2jserver.service.database.MySQLDatabaseService;
|
||||
import com.l2jserver.service.game.scripting.ScriptingService;
|
||||
import com.l2jserver.service.game.scripting.ScriptingServiceImpl;
|
||||
import com.l2jserver.service.game.template.StaticTemplateService;
|
||||
@@ -10,12 +14,22 @@ import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.WorldServiceImpl;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcherImpl;
|
||||
import com.l2jserver.service.logging.Log4JLoggingService;
|
||||
import com.l2jserver.service.logging.LoggingService;
|
||||
import com.l2jserver.service.network.NettyNetworkService;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
|
||||
public class ServiceModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ServiceManager.class).in(Scopes.SINGLETON);
|
||||
bind(LoggingService.class).to(Log4JLoggingService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ConfigurationService.class).to(ProxyConfigurationService.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
bind(DatabaseService.class).to(MySQLDatabaseService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
|
||||
bind(NetworkService.class).to(NettyNetworkService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ScriptingService.class).to(ScriptingServiceImpl.class).in(
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
public class ServiceRestartException extends ServiceException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServiceRestartException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceRestartException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ServiceRestartException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ServiceRestartException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
public class ServiceStartException extends ServiceException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServiceStartException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceStartException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ServiceStartException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ServiceStartException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.l2jserver.service;
|
||||
|
||||
public class ServiceStopException extends ServiceException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServiceStopException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceStopException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ServiceStopException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ServiceStopException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
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;
|
||||
|
||||
public interface Configuration {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Target(value = ElementType.TYPE)
|
||||
public @interface ConfigurationName {
|
||||
String value();
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.METHOD)
|
||||
public @interface ConfigurationPropertyGetter {
|
||||
String name();
|
||||
String defaultValue() default "";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.METHOD)
|
||||
public @interface ConfigurationPropertySetter {
|
||||
String name();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.l2jserver.service.configuration;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
public interface ConfigurationService extends Service {
|
||||
<C extends Configuration> C get(Class<C> config);
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.l2jserver.service.configuration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
|
||||
import com.l2jserver.service.configuration.Configuration.ConfigurationPropertyGetter;
|
||||
import com.l2jserver.service.configuration.Configuration.ConfigurationPropertySetter;
|
||||
import com.l2jserver.util.transformer.Transformer;
|
||||
import com.l2jserver.util.transformer.TransformerFactory;
|
||||
|
||||
public class ProxyConfigurationService extends AbstractService implements
|
||||
ConfigurationService {
|
||||
private File directory = new File("./config");
|
||||
private final Logger logger = LoggerFactory
|
||||
.getLogger(ProxyConfigurationService.class);
|
||||
|
||||
private Map<Class<?>, Object> cache = new WeakHashMap<Class<?>, Object>();
|
||||
|
||||
@Override
|
||||
public void start() throws ServiceStartException {
|
||||
if (!directory.exists())
|
||||
directory.mkdirs();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <C extends Configuration> C get(Class<C> config) {
|
||||
if (cache.containsKey(config))
|
||||
return (C) cache.get(config);
|
||||
logger.info("Trying to create {} proxy", config);
|
||||
Properties properties;
|
||||
try {
|
||||
properties = findProperties(config);
|
||||
} catch (IOException e) {
|
||||
properties = new Properties();
|
||||
logger.info(
|
||||
"Configuration file for {} not found, falling back to default values",
|
||||
config);
|
||||
}
|
||||
C proxy = (C) Proxy.newProxyInstance(this.getClass().getClassLoader(),
|
||||
new Class<?>[] { config }, new ConfigInvocationHandler(
|
||||
properties));
|
||||
cache.put(config, proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
private class ConfigInvocationHandler implements InvocationHandler {
|
||||
private final Properties properties;
|
||||
private Map<String, Object> cache = new WeakHashMap<String, Object>();
|
||||
|
||||
public ConfigInvocationHandler(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
logger.debug("Configuration service, method invoked: {}", method.getName());
|
||||
if (args == null || args.length == 0) {
|
||||
final ConfigurationPropertyGetter getter = method
|
||||
.getAnnotation(ConfigurationPropertyGetter.class);
|
||||
if (getter == null)
|
||||
return null;
|
||||
return get(getter, method.getReturnType());
|
||||
} else if (args.length == 1) {
|
||||
final ConfigurationPropertySetter setter = method
|
||||
.getAnnotation(ConfigurationPropertySetter.class);
|
||||
if (setter == null)
|
||||
return null;
|
||||
set(setter, args[0], method.getParameterTypes()[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object get(ConfigurationPropertyGetter getter, Class<?> type) {
|
||||
if (cache.containsKey(getter.name()))
|
||||
return cache.get(getter.name());
|
||||
Object o = untransform(
|
||||
getRaw(getter.name(), getter.defaultValue()), type);
|
||||
cache.put(getter.name(), o);
|
||||
return o;
|
||||
}
|
||||
|
||||
private void set(ConfigurationPropertySetter setter, Object value,
|
||||
Class<?> type) {
|
||||
if (value != null) {
|
||||
properties.setProperty(setter.name(),
|
||||
transform(value.toString(), type));
|
||||
cache.remove(setter.name());
|
||||
} else {
|
||||
properties.remove(setter.name());
|
||||
cache.remove(setter.name());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
private String getRaw(String key, String defaultValue) {
|
||||
if (properties == null)
|
||||
return defaultValue;
|
||||
if (properties.containsKey(key)) {
|
||||
return (String) properties.get(key);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private Properties findProperties(Class<?> clazz) throws IOException {
|
||||
ConfigurationName config = findAnnotation(ConfigurationName.class,
|
||||
clazz);
|
||||
if (config == null)
|
||||
return null;
|
||||
final Properties prop = new Properties();
|
||||
final File file = new File(directory, config.value() + ".properties");
|
||||
final InputStream in = new FileInputStream(file);
|
||||
try {
|
||||
prop.load(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
private <T extends Annotation> T findAnnotation(Class<T> annotationClass,
|
||||
Class<?> 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;
|
||||
}
|
||||
|
||||
public File getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
public void setDirectory(File directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public abstract class AbstractDAO<T> implements DataAccessObject<T> {
|
||||
protected final DatabaseService database;
|
||||
|
||||
@Inject
|
||||
protected AbstractDAO(DatabaseService database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public DatabaseService getDatabase() {
|
||||
return database;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
|
||||
|
||||
@ConfigurationName("db4o")
|
||||
public interface DB4ODatabaseConfiguration extends DatabaseConfiguration {
|
||||
/**
|
||||
* @return the database file
|
||||
*/
|
||||
@ConfigurationPropertyGetter(name = "db4o.file", defaultValue = "database.bin")
|
||||
File getDatabaseFile();
|
||||
|
||||
/**
|
||||
* @param jdbcUrl
|
||||
* the new database file
|
||||
*/
|
||||
@ConfigurationPropertySetter(name = "db4o.file")
|
||||
void setDatabaseFile(File file);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
import com.l2jserver.service.AbstractService;
|
||||
|
||||
public class DB4ODatabaseService extends AbstractService implements
|
||||
DatabaseService {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
/**
|
||||
* The DAO interface
|
||||
* <p>
|
||||
* TODO make DAO an {@link Iterable}. So if we want to select all objects we can
|
||||
* do like this: <code><pre>
|
||||
* for(final Object o : daoInstance) {
|
||||
* ...
|
||||
* }
|
||||
* </pre></code>
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface DataAccessObject<T> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
import com.l2jserver.service.configuration.Configuration;
|
||||
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
|
||||
|
||||
@ConfigurationName("database")
|
||||
public interface DatabaseConfiguration extends Configuration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
public interface DatabaseService extends Service {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
public interface MySQLDatabaseConfiguration extends DatabaseConfiguration {
|
||||
/**
|
||||
* @return the jdbc url
|
||||
*/
|
||||
@ConfigurationPropertyGetter(name = "jdbc.mysql.url", defaultValue = "jdbc:mysql://localhost/l2jserver2")
|
||||
String getJdbcUrl();
|
||||
|
||||
/**
|
||||
* @param jdbcUrl
|
||||
* the new jdbc url
|
||||
*/
|
||||
@ConfigurationPropertySetter(name = "jdbc.mysql.url")
|
||||
void setJdbcUrl(String jdbcUrl);
|
||||
|
||||
/**
|
||||
* @return the jdbc driver class
|
||||
*/
|
||||
@ConfigurationPropertyGetter(name = "jdbc.mysql.driver", defaultValue = "com.mysql.jdbc.Driver")
|
||||
String getDriver();
|
||||
|
||||
/**
|
||||
* @param driver
|
||||
* the new jdbc driver
|
||||
*/
|
||||
@ConfigurationPropertySetter(name = "jdbc.mysql.driver")
|
||||
void setDriver(Class<?> driver);
|
||||
|
||||
/**
|
||||
* @return the mysql database username
|
||||
*/
|
||||
@ConfigurationPropertyGetter(name = "jdbc.mysql.username", defaultValue = "l2j")
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* @param username
|
||||
* the mysql database username
|
||||
*/
|
||||
@ConfigurationPropertySetter(name = "jdbc.mysql.username")
|
||||
void setUsername(String username);
|
||||
|
||||
/**
|
||||
* @return the mysql database password
|
||||
*/
|
||||
@ConfigurationPropertyGetter(name = "jdbc.mysql.password", defaultValue = "changeme")
|
||||
String getPassword();
|
||||
|
||||
/**
|
||||
* @param password
|
||||
* the mysql database password
|
||||
*/
|
||||
@ConfigurationPropertySetter(name = "jdbc.mysql.password")
|
||||
void setPassword(String password);
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package com.l2jserver.service.database;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.dbcp.ConnectionFactory;
|
||||
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
|
||||
import org.apache.commons.dbcp.PoolableConnectionFactory;
|
||||
import org.apache.commons.dbcp.PoolingDataSource;
|
||||
import org.apache.commons.pool.ObjectPool;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.util.ArrayIterator;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class MySQLDatabaseService extends AbstractService implements
|
||||
DatabaseService {
|
||||
private final MySQLDatabaseConfiguration config;
|
||||
private final Logger logger = LoggerFactory
|
||||
.getLogger(MySQLDatabaseService.class);
|
||||
|
||||
private ObjectPool connectionPool;
|
||||
private ConnectionFactory connectionFactory;
|
||||
@SuppressWarnings("unused")
|
||||
private PoolableConnectionFactory poolableConnectionFactory;
|
||||
private PoolingDataSource dataSource;
|
||||
|
||||
@Inject
|
||||
public MySQLDatabaseService(ConfigurationService configService) {
|
||||
config = configService.get(MySQLDatabaseConfiguration.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws ServiceStartException {
|
||||
connectionPool = new GenericObjectPool(null);
|
||||
connectionFactory = new DriverManagerConnectionFactory(
|
||||
config.getJdbcUrl(), config.getUsername(), config.getPassword());
|
||||
poolableConnectionFactory = new PoolableConnectionFactory(
|
||||
connectionFactory, connectionPool, null, null, false, true);
|
||||
dataSource = new PoolingDataSource(connectionPool);
|
||||
}
|
||||
|
||||
public <T> T query(Query<T> query) {
|
||||
try {
|
||||
final Connection conn = dataSource.getConnection();
|
||||
try {
|
||||
return query.query(conn);
|
||||
} catch (SQLException e) {
|
||||
logger.error("Error executing query", e);
|
||||
return null;
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.error("Could not open database connection", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws ServiceStopException {
|
||||
try {
|
||||
if (connectionPool != null)
|
||||
connectionPool.close();
|
||||
} catch (Exception e) {
|
||||
logger.error("Error stopping database service", e);
|
||||
throw new ServiceStopException(e);
|
||||
} finally {
|
||||
connectionPool = null;
|
||||
connectionFactory = null;
|
||||
poolableConnectionFactory = null;
|
||||
dataSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Query<R> {
|
||||
R query(Connection conn) throws SQLException;
|
||||
}
|
||||
|
||||
public static abstract class InsertUpdateQuery<T> implements Query<Integer> {
|
||||
private final Iterator<T> iterator;
|
||||
|
||||
public InsertUpdateQuery(T... objects) {
|
||||
this(new ArrayIterator<T>(objects));
|
||||
}
|
||||
|
||||
public InsertUpdateQuery(Iterator<T> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer query(Connection conn) throws SQLException {
|
||||
int rows = 0;
|
||||
while (iterator.hasNext()) {
|
||||
final T object = iterator.next();
|
||||
final PreparedStatement st = conn.prepareStatement(query());
|
||||
this.parametize(st, object);
|
||||
rows += st.executeUpdate();
|
||||
final Mapper<T> mapper = keyMapper(object);
|
||||
if (mapper == null)
|
||||
continue;
|
||||
final ResultSet rs = st.getGeneratedKeys();
|
||||
while (rs.next()) {
|
||||
mapper.map(rs);
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
protected abstract String query();
|
||||
|
||||
protected abstract void parametize(PreparedStatement st, T object)
|
||||
throws SQLException;
|
||||
|
||||
protected Mapper<T> keyMapper(T object) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class SelectListQuery<T> implements Query<List<T>> {
|
||||
@Override
|
||||
public List<T> query(Connection conn) throws SQLException {
|
||||
final PreparedStatement st = conn.prepareStatement(query());
|
||||
parametize(st);
|
||||
st.execute();
|
||||
final List<T> list = CollectionFactory.newList(null);
|
||||
final ResultSet rs = st.getResultSet();
|
||||
while (rs.next()) {
|
||||
list.add(mapper().map(rs));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected abstract String query();
|
||||
|
||||
protected void parametize(PreparedStatement st) throws SQLException {
|
||||
}
|
||||
|
||||
protected abstract Mapper<T> mapper();
|
||||
}
|
||||
|
||||
public static abstract class SelectSingleQuery<T> implements Query<T> {
|
||||
@Override
|
||||
public T query(Connection conn) throws SQLException {
|
||||
final PreparedStatement st = conn.prepareStatement(query());
|
||||
parametize(st);
|
||||
st.execute();
|
||||
final ResultSet rs = st.getResultSet();
|
||||
while (rs.next()) {
|
||||
return mapper().map(rs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract String query();
|
||||
|
||||
protected abstract void parametize(PreparedStatement st)
|
||||
throws SQLException;
|
||||
|
||||
protected abstract Mapper<T> mapper();
|
||||
}
|
||||
|
||||
public interface Mapper<T> {
|
||||
T map(ResultSet rs) throws SQLException;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.l2jserver.service.logging;
|
||||
|
||||
import org.apache.log4j.BasicConfigurator;
|
||||
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
|
||||
public class Log4JLoggingService extends AbstractService implements
|
||||
LoggingService {
|
||||
@Override
|
||||
public void stop() throws ServiceStopException {
|
||||
BasicConfigurator.configure();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.l2jserver.service.logging;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
/**
|
||||
* The logging service is used to get instances of the {@link Logger} class.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface LoggingService extends Service {
|
||||
}
|
||||
Reference in New Issue
Block a user