> createQuery(
+ ODatabaseDocumentTx database);
+
+ /**
+ * Return the mapper that will bind {@link ResultSet} objects into an
+ * T object instance. The mapper will need to create the object
+ * instance.
+ *
+ * Note: This method will be called for each row, an thus is a
+ * good idea to create a new instance on each call!
+ *
+ * @return the mapper instance
+ */
+ protected abstract Mapper mapper();
+ }
+
+ /**
+ * An select query that returns a single object of type T
+ *
+ * @author Rogiel
+ *
+ * @param
+ * the query return type
+ */
+ public static abstract class SelectSingleQuery implements Query {
+ /**
+ * The logger
+ */
+ private final Logger log = LoggerFactory
+ .getLogger(SelectSingleQuery.class);
+
+ @Override
+ public T query(ODatabaseDocumentTx database) throws SQLException {
+ Preconditions.checkNotNull(database, "database");
+
+ log.debug("Starting SELECT single query execution");
+
+ List result = database.query(createQuery(database));
+ final Mapper mapper = mapper();
+ log.debug("Database returned {}", result);
+ for (final ODocument document : result) {
+ log.debug("Mapping row with {}", mapper);
+ final T obj = mapper.map(document);
+ if (obj == null) {
+ log.debug("Mapper {} returned a null row", mapper);
+ continue;
+ }
+ if (obj instanceof Model)
+ ((Model>) obj).setObjectDesire(ObjectDesire.NONE);
+ log.debug("Mapper {} returned {}", mapper, obj);
+ return obj;
+ }
+ return null;
+ }
+
+ /**
+ * Creates the prepared query for execution
+ *
+ * @param database
+ * the database
+ *
+ * @return the prepared query
+ */
+ protected abstract ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database);
+
+ /**
+ * Return the mapper that will bind {@link ResultSet} objects into an
+ * T object instance. The mapper will need to create the object
+ * instance.
+ *
+ * Note: This method will be called for each row, an thus is a
+ * good idea to create a new instance on each call!
+ *
+ * @return the mapper instance
+ */
+ protected abstract Mapper mapper();
+ }
+
+ /**
+ * The {@link Mapper} maps an {@link ResultSet} into an object T
+ *
+ * @author Rogiel
+ *
+ * @param
+ * the object type
+ */
+ public interface Mapper {
+ /**
+ * Map the result set value into an object.
+ *
+ * Note: it is required to call {@link ResultSet#next()}, since
+ * it is called by the {@link Query}.
+ *
+ * @param document
+ * the resulted document
+ * @return the created instance
+ * @throws SQLException
+ * if any SQL error occur
+ */
+ T map(ODocument document) throws SQLException;
+ }
+
+ /**
+ * The cached mapper will try to lookup the result in the cache, before
+ * create a new instance. If the instance is not found in the cache, then
+ * the {@link Mapper} implementation is called to create the object. Note
+ * that the ID, used for the cache lookup, will be reused. After creation,
+ * the cache is updated.
+ *
+ * @author Rogiel
+ *
+ * @param
+ * the object type
+ * @param
+ * the id type
+ */
+ public abstract static class CachedMapper, I extends ID>>
+ implements Mapper {
+ /**
+ * The logger
+ */
+ private final Logger log = LoggerFactory
+ .getLogger(SelectSingleQuery.class);
+
+ /**
+ * The database service instance
+ */
+ private final AbstractOrientDatabaseService database;
+
+ /**
+ * The {@link ID} mapper
+ */
+ private final Mapper idMapper;
+
+ /**
+ * Creates a new instance
+ *
+ * @param database
+ * the database service
+ * @param idMapper
+ * the {@link ID} {@link Mapper}
+ */
+ public CachedMapper(AbstractOrientDatabaseService database,
+ Mapper idMapper) {
+ this.database = database;
+ this.idMapper = idMapper;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final T map(ODocument document) throws SQLException {
+ log.debug("Mapping row {} ID with {}", document, idMapper);
+ final I id = idMapper.map(document);
+ Preconditions.checkNotNull(id, "id");
+
+ log.debug("ID={}, locating cached object", id);
+
+ if (database.hasCachedObject(id))
+ return (T) database.getCachedObject(id);
+
+ log.debug("Cached object not found, creating...");
+
+ final T object = map(id, document);
+ if (object != null)
+ database.updateCache(id, object);
+ log.debug("Object {} created", object);
+ return object;
+ }
+
+ /**
+ * Maps an uncached object. Once mapping is complete, it will be added
+ * to the cache.
+ *
+ * @param id
+ * the object id
+ * @param document
+ * the document result
+ * @return the created object
+ * @throws SQLException
+ * if any SQL error occur
+ */
+ protected abstract T map(I id, ODocument document) throws SQLException;
+ }
+}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DAOResolver.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DAOResolver.java
new file mode 100644
index 000000000..edf8e2007
--- /dev/null
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DAOResolver.java
@@ -0,0 +1,66 @@
+package com.l2jserver.service.database;
+
+import com.l2jserver.model.Model;
+import com.l2jserver.model.id.ID;
+
+public interface DAOResolver {
+ /**
+ * Returns the {@link DataAccessObject} used to retrieve and save objects of
+ * type
+ *
+ * @param
+ * the {@link Model} type
+ * @param
+ * the {@link ID} type
+ * @param modelObject
+ * the model object
+ * @return the {@link DataAccessObject} for {@link Model}
+ */
+ , M extends Model> DataAccessObject getDAO(
+ M modelObject);
+
+ /**
+ * Returns the {@link DataAccessObject} used to retrieve and save objects of
+ * type
+ *
+ * @param
+ * the {@link Model} type
+ * @param
+ * the {@link ID} type
+ * @param modelClass
+ * the model class
+ * @return the {@link DataAccessObject} for {@link Model}
+ */
+ , I extends ID> DataAccessObject getDAO(
+ Class modelClass);
+
+ /**
+ * Returns the {@link DataAccessObject} used to retrieve and save objects of
+ * type M which use {@link ID} of type I
+ *
+ * @param
+ * the {@link Model} type
+ * @param
+ * the {@link ID} type
+ * @param modelIdObject
+ * the model {@link ID} object
+ * @return the {@link DataAccessObject} for {@link Model}
+ */
+ , M extends Model> DataAccessObject getDAOFromID(
+ I modelIdObject);
+
+ /**
+ * Returns the {@link DataAccessObject} used to retrieve and save objects of
+ * type M which use {@link ID} of type I
+ *
+ * @param
+ * the {@link Model} type
+ * @param
+ * the {@link ID} type
+ * @param modelIdType
+ * the model {@link ID} class
+ * @return the {@link DataAccessObject} for {@link Model}
+ */
+ , M extends Model>> DataAccessObject getDAOFromID(
+ Class modelIdType);
+}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java
index d04698857..492052884 100644
--- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java
@@ -16,8 +16,6 @@
*/
package com.l2jserver.service.database;
-import com.l2jserver.model.Model;
-import com.l2jserver.model.id.ID;
import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration;
@@ -48,19 +46,4 @@ public interface DatabaseService extends Service {
@ConfigurationName("database")
public interface DatabaseConfiguration extends ServiceConfiguration {
}
-
- /**
- * Returns the {@link DataAccessObject} used to retrieve and save objects of
- * type
- *
- * @param
- * the {@link Model} type
- * @param
- * the {@link ID} type
- * @param model
- * the model class
- * @return the {@link DataAccessObject} for {@link Model}
- */
- , I extends ID> DataAccessObject getDAO(
- Class model);
}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java
new file mode 100644
index 000000000..c0d398d9e
--- /dev/null
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java
@@ -0,0 +1,44 @@
+/*
+ * 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.database.orientdb;
+
+import com.l2jserver.model.Model;
+import com.l2jserver.model.id.ID;
+import com.l2jserver.service.database.AbstractDAO;
+import com.l2jserver.service.database.AbstractOrientDatabaseService;
+import com.l2jserver.service.database.DatabaseService;
+
+/**
+ * @author Rogiel
+ * @param
+ * the model type
+ * @param
+ * the id type
+ */
+public abstract class AbstractOrientDBDAO, I extends ID>>
+ extends AbstractDAO {
+ protected final AbstractOrientDatabaseService database;
+
+ /**
+ * @param database
+ * the database instance
+ */
+ protected AbstractOrientDBDAO(DatabaseService database) {
+ super(database);
+ this.database = (AbstractOrientDatabaseService) database;
+ }
+}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerDAOResolver.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerDAOResolver.java
new file mode 100644
index 000000000..38e447175
--- /dev/null
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerDAOResolver.java
@@ -0,0 +1,101 @@
+/*
+ * 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.database;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.l2jserver.model.Model;
+import com.l2jserver.model.dao.CharacterDAO;
+import com.l2jserver.model.dao.ClanDAO;
+import com.l2jserver.model.dao.ItemDAO;
+import com.l2jserver.model.dao.NPCDAO;
+import com.l2jserver.model.dao.PetDAO;
+import com.l2jserver.model.id.ID;
+import com.l2jserver.model.id.object.CharacterID;
+import com.l2jserver.model.id.object.ClanID;
+import com.l2jserver.model.id.object.ItemID;
+import com.l2jserver.model.id.object.NPCID;
+import com.l2jserver.model.id.object.PetID;
+import com.l2jserver.model.world.Clan;
+import com.l2jserver.model.world.Item;
+import com.l2jserver.model.world.L2Character;
+import com.l2jserver.model.world.NPC;
+import com.l2jserver.model.world.Pet;
+import com.l2jserver.util.ClassUtils;
+
+/**
+ * @author Rogiel
+ *
+ */
+public class GameServerDAOResolver implements DAOResolver {
+ private final Injector injector;
+
+ @Inject
+ private GameServerDAOResolver(Injector injector) {
+ this.injector = injector;
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public , M extends Model> DataAccessObject getDAO(
+ M modelObject) {
+ return (DataAccessObject) getDAO(modelObject.getClass());
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public , I extends ID> DataAccessObject getDAO(
+ Class modelClass) {
+ if (ClassUtils.isSubclass(modelClass, L2Character.class)) {
+ return (DataAccessObject) injector.getInstance(CharacterDAO.class);
+ } else if (ClassUtils.isSubclass(modelClass, Clan.class)) {
+ return (DataAccessObject) injector.getInstance(ClanDAO.class);
+ } else if (ClassUtils.isSubclass(modelClass, Item.class)) {
+ return (DataAccessObject) injector.getInstance(ItemDAO.class);
+ } else if (ClassUtils.isSubclass(modelClass, NPC.class)) {
+ return (DataAccessObject) injector.getInstance(NPCDAO.class);
+ } else if (ClassUtils.isSubclass(modelClass, Pet.class)) {
+ return (DataAccessObject) injector.getInstance(PetDAO.class);
+ }
+ return null;
+ }
+
+ @Override
+ @SuppressWarnings({ "unchecked" })
+ public , M extends Model> DataAccessObject getDAOFromID(
+ I modelIdObject) {
+ return (DataAccessObject) getDAOFromID(modelIdObject.getClass());
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public , M extends Model>> DataAccessObject getDAOFromID(
+ Class modelIdType) {
+ if (ClassUtils.isSubclass(modelIdType, CharacterID.class)) {
+ return (DataAccessObject) injector.getInstance(CharacterDAO.class);
+ } else if (ClassUtils.isSubclass(modelIdType, ClanID.class)) {
+ return (DataAccessObject) injector.getInstance(ClanDAO.class);
+ } else if (ClassUtils.isSubclass(modelIdType, ItemID.class)) {
+ return (DataAccessObject) injector.getInstance(ItemDAO.class);
+ } else if (ClassUtils.isSubclass(modelIdType, NPCID.class)) {
+ return (DataAccessObject) injector.getInstance(NPCDAO.class);
+ } else if (ClassUtils.isSubclass(modelIdType, PetID.class)) {
+ return (DataAccessObject) injector.getInstance(PetDAO.class);
+ }
+ return null;
+ }
+}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java
index d2b0040db..e1c23916d 100644
--- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java
@@ -18,26 +18,15 @@ package com.l2jserver.service.database;
import java.sql.ResultSet;
-import com.google.inject.Injector;
+import com.google.inject.Inject;
import com.l2jserver.model.Model;
-import com.l2jserver.model.dao.CharacterDAO;
-import com.l2jserver.model.dao.ClanDAO;
-import com.l2jserver.model.dao.ItemDAO;
-import com.l2jserver.model.dao.NPCDAO;
-import com.l2jserver.model.dao.PetDAO;
import com.l2jserver.model.id.ID;
-import com.l2jserver.model.world.Clan;
-import com.l2jserver.model.world.Item;
-import com.l2jserver.model.world.L2Character;
-import com.l2jserver.model.world.NPC;
-import com.l2jserver.model.world.Pet;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.threading.ThreadService;
import com.l2jserver.service.game.template.TemplateService;
-import com.l2jserver.util.ClassUtils;
/**
* This is an implementation of {@link DatabaseService} that provides an layer
@@ -77,43 +66,20 @@ import com.l2jserver.util.ClassUtils;
ConfigurationService.class, TemplateService.class, ThreadService.class })
public class GameServerJDBCDatabaseService extends AbstractJDBCDatabaseService
implements DatabaseService {
- /**
- * The Google Guice {@link Injector}. It is used to get DAO instances.
- */
- private final Injector injector;
-
/**
* @param configService
* the config service
- * @param injector
- * the Guice {@link Injector}
* @param cacheService
* the cache service
* @param threadService
* the thread service
+ * @param daoResolver
+ * the {@link DataAccessObject DAO} resolver
*/
+ @Inject
public GameServerJDBCDatabaseService(ConfigurationService configService,
- Injector injector, CacheService cacheService,
- ThreadService threadService) {
- super(configService, cacheService, threadService);
- this.injector = injector;
- }
-
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public , I extends ID> DataAccessObject getDAO(
- Class model) {
- if (ClassUtils.isSubclass(model, L2Character.class)) {
- return (DataAccessObject) injector.getInstance(CharacterDAO.class);
- } else if (ClassUtils.isSubclass(model, Clan.class)) {
- return (DataAccessObject) injector.getInstance(ClanDAO.class);
- } else if (ClassUtils.isSubclass(model, Item.class)) {
- return (DataAccessObject) injector.getInstance(ItemDAO.class);
- } else if (ClassUtils.isSubclass(model, NPC.class)) {
- return (DataAccessObject) injector.getInstance(NPCDAO.class);
- } else if (ClassUtils.isSubclass(model, Pet.class)) {
- return (DataAccessObject) injector.getInstance(PetDAO.class);
- }
- return null;
+ CacheService cacheService, ThreadService threadService,
+ DAOResolver daoResolver) {
+ super(configService, cacheService, threadService, daoResolver);
}
}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerOrientDatabaseService.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerOrientDatabaseService.java
new file mode 100644
index 000000000..c52e5a198
--- /dev/null
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerOrientDatabaseService.java
@@ -0,0 +1,85 @@
+/*
+ * 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.database;
+
+import java.sql.ResultSet;
+
+import com.google.inject.Inject;
+import com.l2jserver.model.Model;
+import com.l2jserver.model.id.ID;
+import com.l2jserver.service.AbstractService.Depends;
+import com.l2jserver.service.cache.CacheService;
+import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.service.core.LoggingService;
+import com.l2jserver.service.core.threading.ThreadService;
+import com.l2jserver.service.game.template.TemplateService;
+
+/**
+ * This is an implementation of {@link DatabaseService} that provides an layer
+ * to JDBC.
+ *
+ * Internal specification
The
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
+ * Query} object
+ *
+ * If you wish to implement a new {@link DataAccessObject} you should try not
+ * use {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
+ * Query} object directly because it only provides low level access to the JDBC
+ * architecture. Instead, you could use an specialized class, like
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery
+ * InsertUpdateQuery} ,
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery
+ * SelectListQuery} or
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectSingleQuery
+ * SelectSingleQuery} . If you do need low level access, feel free to use the
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
+ * Query} class directly.
+ *
+ * The
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
+ * Mapper} object
+ *
+ * The {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
+ * Mapper} object maps an JDBC {@link ResultSet} into an Java {@link Object}.
+ * All {@link Model} objects support
+ * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper
+ * CachedMapper} that will cache result based on its {@link ID} and always use
+ * the same object with the same {@link ID}.
+ *
+ * @author Rogiel
+ */
+@Depends({ LoggingService.class, CacheService.class,
+ ConfigurationService.class, TemplateService.class, ThreadService.class })
+public class GameServerOrientDatabaseService extends
+ AbstractOrientDatabaseService implements DatabaseService {
+ /**
+ * @param configService
+ * the config service
+ * @param cacheService
+ * the cache service
+ * @param threadService
+ * the thread service
+ * @param daoResolver
+ * the {@link DataAccessObject DAO} resolver
+ */
+ @Inject
+ public GameServerOrientDatabaseService(ConfigurationService configService,
+ CacheService cacheService, ThreadService threadService,
+ DAOResolver daoResolver) {
+ super(configService, cacheService, threadService, daoResolver);
+ }
+}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java
new file mode 100644
index 000000000..c0d398d9e
--- /dev/null
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java
@@ -0,0 +1,44 @@
+/*
+ * 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.database.orientdb;
+
+import com.l2jserver.model.Model;
+import com.l2jserver.model.id.ID;
+import com.l2jserver.service.database.AbstractDAO;
+import com.l2jserver.service.database.AbstractOrientDatabaseService;
+import com.l2jserver.service.database.DatabaseService;
+
+/**
+ * @author Rogiel
+ * @param
+ * the model type
+ * @param
+ * the id type
+ */
+public abstract class AbstractOrientDBDAO, I extends ID>>
+ extends AbstractDAO {
+ protected final AbstractOrientDatabaseService database;
+
+ /**
+ * @param database
+ * the database instance
+ */
+ protected AbstractOrientDBDAO(DatabaseService database) {
+ super(database);
+ this.database = (AbstractOrientDatabaseService) database;
+ }
+}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java
new file mode 100644
index 000000000..701514500
--- /dev/null
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java
@@ -0,0 +1,465 @@
+/*
+ * 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.database.orientdb;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.List;
+
+import com.google.inject.Inject;
+import com.l2jserver.model.dao.CharacterDAO;
+import com.l2jserver.model.id.AccountID;
+import com.l2jserver.model.id.object.CharacterID;
+import com.l2jserver.model.id.object.ClanID;
+import com.l2jserver.model.id.object.provider.CharacterIDProvider;
+import com.l2jserver.model.id.object.provider.ClanIDProvider;
+import com.l2jserver.model.id.provider.AccountIDProvider;
+import com.l2jserver.model.id.template.CharacterTemplateID;
+import com.l2jserver.model.id.template.provider.CharacterTemplateIDProvider;
+import com.l2jserver.model.template.CharacterTemplate;
+import com.l2jserver.model.template.actor.ActorSex;
+import com.l2jserver.model.template.character.CharacterClass;
+import com.l2jserver.model.template.character.CharacterRace;
+import com.l2jserver.model.world.Clan;
+import com.l2jserver.model.world.L2Character;
+import com.l2jserver.model.world.character.CharacterAppearance;
+import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace;
+import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
+import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
+import com.l2jserver.service.database.AbstractOrientDatabaseService.CachedMapper;
+import com.l2jserver.service.database.AbstractOrientDatabaseService.InsertUpdateQuery;
+import com.l2jserver.service.database.AbstractOrientDatabaseService.Mapper;
+import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectListQuery;
+import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectSingleQuery;
+import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.util.geometry.Point3D;
+import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
+import com.orientechnologies.orient.core.query.nativ.ONativeSynchQuery;
+import com.orientechnologies.orient.core.query.nativ.OQueryContextNativeSchema;
+import com.orientechnologies.orient.core.record.impl.ODocument;
+
+/**
+ * @author Rogiel
+ *
+ */
+public class OrientDBCharacterDAO extends
+ AbstractOrientDBDAO implements CharacterDAO {
+ /**
+ * The {@link CharacterID} factory
+ */
+ private final CharacterIDProvider idFactory;
+ /**
+ * The {@link CharacterTemplateID} factory
+ */
+ private final CharacterTemplateIDProvider templateIdFactory;
+ /**
+ * The {@link AccountID} factory
+ */
+ private final AccountIDProvider accountIdFactory;
+ /**
+ * The {@link ClanID} factory
+ */
+ private final ClanIDProvider clanIdFactory;
+
+ /**
+ * Character table name
+ */
+ public static final String CLASS_NAME = L2Character.class.getSimpleName();
+ // FIELDS
+ public static final String CHAR_ID = "character_id";
+ public static final String ACCOUNT_ID = "account_id";
+ public static final String CLAN_ID = "clan_id";
+ public static final String NAME = "name";
+
+ public static final String RACE = "race";
+ public static final String CLASS = "class";
+ public static final String SEX = "sex";
+
+ public static final String LEVEL = "level";
+ public static final String EXPERIENCE = "experience";
+ public static final String SP = "sp";
+
+ public static final String HP = "hp";
+ public static final String MP = "mp";
+ public static final String CP = "cp";
+
+ public static final String POINT_X = "point_x";
+ public static final String POINT_Y = "point_y";
+ public static final String POINT_Z = "point_z";
+ public static final String POINT_ANGLE = "point_angle";
+
+ public static final String APPEARANCE_HAIR_STYLE = "appearance_hair_style";
+ public static final String APPEARANCE_HAIR_COLOR = "appearance_hair_color";
+ public static final String APPEARANCE_FACE = "apperance_face";
+
+ /**
+ * The mapper for {@link CharacterID}
+ */
+ private final Mapper idMapper = new Mapper() {
+ @Override
+ public CharacterID map(ODocument document) throws SQLException {
+ return idFactory.resolveID((Integer) document.field(CHAR_ID));
+ }
+ };
+
+ /**
+ * The {@link Mapper} for {@link L2Character}
+ */
+ private final Mapper mapper = new CachedMapper(
+ database, idMapper) {
+ @Override
+ protected L2Character map(CharacterID id, ODocument document)
+ throws SQLException {
+ final CharacterClass charClass = (CharacterClass) document
+ .field(CLASS);
+ final CharacterTemplateID templateId = templateIdFactory
+ .resolveID(charClass.id);
+ final CharacterTemplate template = templateId.getTemplate();
+
+ final L2Character character = template.create();
+
+ character.setID(id);
+ character.setAccountID(accountIdFactory.resolveID((String) document
+ .field(ACCOUNT_ID)));
+ if (document.containsField(CLAN_ID))
+ character.setClanID(clanIdFactory.resolveID((Integer) document
+ .field(CLAN_ID)));
+
+ character.setName((String) document.field(NAME));
+
+ character.setRace((CharacterRace) document.field(RACE));
+ character.setCharacterClass((CharacterClass) document.field(CLASS));
+ character.setSex((ActorSex) document.field(SEX));
+
+ character.setLevel((Integer) document.field(LEVEL));
+ character.setExperience((Long) document.field(EXPERIENCE));
+ character.setSP((Integer) document.field(SP));
+
+ character.setHP((Double) document.field(HP));
+ character.setMP((Double) document.field(MP));
+ character.setCP((Double) document.field(CP));
+
+ character.setPoint(Point3D.fromXYZA(
+ (Integer) document.field(POINT_X),
+ (Integer) document.field(POINT_Y),
+ (Integer) document.field(POINT_Z),
+ (Double) document.field(POINT_ANGLE)));
+
+ // appearance
+ character.getAppearance().setHairStyle(
+ (CharacterHairStyle) document.field(APPEARANCE_HAIR_STYLE));
+ character.getAppearance().setHairColor(
+ (CharacterHairColor) document.field(APPEARANCE_HAIR_COLOR));
+ character.getAppearance().setFace(
+ (CharacterFace) document.field(APPEARANCE_FACE));
+
+ return character;
+ }
+ };
+
+ /**
+ * @param database
+ * the database service
+ * @param idFactory
+ * the character id provider
+ * @param templateIdFactory
+ * the template id provider
+ * @param accountIdFactory
+ * the account id provider
+ * @param clanIdFactory
+ * the clan id provider
+ */
+ @Inject
+ protected OrientDBCharacterDAO(DatabaseService database,
+ final CharacterIDProvider idFactory,
+ CharacterTemplateIDProvider templateIdFactory,
+ AccountIDProvider accountIdFactory, ClanIDProvider clanIdFactory) {
+ super(database);
+ this.idFactory = idFactory;
+ this.templateIdFactory = templateIdFactory;
+ this.accountIdFactory = accountIdFactory;
+ this.clanIdFactory = clanIdFactory;
+ }
+
+ @Override
+ public L2Character select(final CharacterID id) {
+ return database.query(new SelectSingleQuery() {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database) {
+ return new ONativeSynchQuery>(
+ database, CLASS_NAME,
+ new OQueryContextNativeSchema()) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean filter(
+ OQueryContextNativeSchema criteria) {
+ return criteria.field(CHAR_ID).eq(id.getID()).go();
+ };
+ };
+ }
+
+ @Override
+ protected Mapper mapper() {
+ return mapper;
+ }
+ });
+ }
+
+ @Override
+ public Collection selectIDs() {
+ return database.query(new SelectListQuery() {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database) {
+ return new ONativeSynchQuery>(
+ database, CLASS_NAME,
+ new OQueryContextNativeSchema()) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean filter(
+ OQueryContextNativeSchema criteria) {
+ return true;
+ };
+ };
+ }
+
+ @Override
+ protected Mapper mapper() {
+ return idMapper;
+ }
+ });
+ }
+
+ @Override
+ public boolean insert(L2Character object) {
+ return database.query(new InsertUpdateQuery(object) {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database, L2Character object) {
+ return null;
+ }
+
+ @Override
+ protected ODocument update(ODocument document, L2Character character)
+ throws SQLException {
+ return null;
+ }
+
+ @Override
+ protected ODocument insert(ODocument document, L2Character character)
+ throws SQLException {
+ final CharacterAppearance appearance = character
+ .getAppearance();
+
+ document.field(CHAR_ID, character.getID().getID());
+ document.field(ACCOUNT_ID, character.getAccountID().getID());
+ if (character.getClanID() != null)
+ document.field(CLAN_ID, character.getClanID().getID());
+
+ document.field(NAME, character.getName());
+
+ document.field(RACE, character.getRace().name());
+ document.field(CLASS, character.getCharacterClass().name());
+ document.field(SEX, character.getSex().name());
+
+ document.field(LEVEL, character.getLevel());
+ document.field(EXPERIENCE, character.getExperience());
+ document.field(SP, character.getSP());
+
+ document.field(HP, character.getHP());
+ document.field(MP, character.getMP());
+ document.field(CP, character.getCP());
+
+ document.field(POINT_X, character.getPoint().getX());
+ document.field(POINT_Y, character.getPoint().getY());
+ document.field(POINT_Z, character.getPoint().getZ());
+ document.field(POINT_ANGLE, character.getPoint().getAngle());
+
+ // appearance
+ document.field(APPEARANCE_HAIR_STYLE, appearance.getHairStyle()
+ .name());
+ document.field(APPEARANCE_HAIR_COLOR, appearance.getHairColor()
+ .name());
+ document.field(APPEARANCE_FACE, appearance.getFace().name());
+
+ return document;
+ }
+ }) != 0;
+ }
+
+ @Override
+ public boolean update(final L2Character character) {
+ return database.query(new InsertUpdateQuery(character) {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database, final L2Character character) {
+ return new ONativeSynchQuery>(
+ database, CLASS_NAME,
+ new OQueryContextNativeSchema()) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean filter(
+ OQueryContextNativeSchema criteria) {
+ return criteria.field(CHAR_ID)
+ .eq(character.getID().getID()).go();
+ };
+ };
+ }
+
+ @Override
+ protected ODocument update(ODocument document, L2Character character)
+ throws SQLException {
+ final CharacterAppearance appearance = character
+ .getAppearance();
+
+ document.field(ACCOUNT_ID, character.getAccountID().getID());
+ if (character.getClanID() != null)
+ document.field(CLAN_ID, character.getClanID().getID());
+
+ document.field(NAME, character.getName());
+
+ document.field(RACE, character.getRace().name());
+ document.field(CLASS, character.getCharacterClass().name());
+ document.field(SEX, character.getSex().name());
+
+ document.field(LEVEL, character.getLevel());
+ document.field(EXPERIENCE, character.getExperience());
+ document.field(SP, character.getSP());
+
+ document.field(HP, character.getHP());
+ document.field(MP, character.getMP());
+ document.field(CP, character.getCP());
+
+ document.field(POINT_X, character.getPoint().getX());
+ document.field(POINT_Y, character.getPoint().getY());
+ document.field(POINT_Z, character.getPoint().getZ());
+ document.field(POINT_ANGLE, character.getPoint().getAngle());
+
+ // appearance
+ document.field(APPEARANCE_HAIR_STYLE, appearance.getHairStyle()
+ .name());
+ document.field(APPEARANCE_HAIR_COLOR, appearance.getHairColor()
+ .name());
+ document.field(APPEARANCE_FACE, appearance.getFace().name());
+
+ return document;
+ }
+
+ @Override
+ protected ODocument insert(ODocument document, L2Character character)
+ throws SQLException {
+ return null;
+ }
+ }) != 0;
+ }
+
+ @Override
+ public boolean delete(L2Character object) {
+ return database.query(new InsertUpdateQuery(object) {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database, final L2Character character) {
+ return new ONativeSynchQuery>(
+ database, CLASS_NAME,
+ new OQueryContextNativeSchema()) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean filter(
+ OQueryContextNativeSchema criteria) {
+ return criteria.field(CHAR_ID)
+ .eq(character.getID().getID()).go();
+ };
+ };
+ }
+
+ @Override
+ protected ODocument update(ODocument document, L2Character character)
+ throws SQLException {
+ document.delete();
+ return null;
+ }
+
+ @Override
+ protected ODocument insert(ODocument document, L2Character character)
+ throws SQLException {
+ return null;
+ }
+ }) != 0;
+ }
+
+ @Override
+ public void load(Clan clan) {
+
+ }
+
+ @Override
+ public L2Character selectByName(final String name) {
+ return database.query(new SelectSingleQuery() {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database) {
+ return new ONativeSynchQuery>(
+ database, CLASS_NAME,
+ new OQueryContextNativeSchema()) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean filter(
+ OQueryContextNativeSchema criteria) {
+ return criteria.field(NAME).eq(name).go();
+ };
+ };
+ }
+
+ @Override
+ protected Mapper mapper() {
+ return mapper;
+ }
+ });
+ }
+
+ @Override
+ public List selectByAccount(final AccountID account) {
+ return database.query(new SelectListQuery() {
+ @Override
+ protected ONativeSynchQuery> createQuery(
+ ODatabaseDocumentTx database) {
+ return new ONativeSynchQuery>(
+ database, CLASS_NAME,
+ new OQueryContextNativeSchema()) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean filter(
+ OQueryContextNativeSchema criteria) {
+ return criteria.field(ACCOUNT_ID).eq(account.getID()).go();
+ };
+ };
+ }
+
+ @Override
+ protected Mapper mapper() {
+ return mapper;
+ }
+ });
+ }
+}
diff --git a/l2jserver2-loginserver/src/main/java/com/l2jserver/service/database/LoginServerJDBCDatabaseService.java b/l2jserver2-loginserver/src/main/java/com/l2jserver/service/database/LoginServerJDBCDatabaseService.java
index 157ffb9ce..d1469efe8 100644
--- a/l2jserver2-loginserver/src/main/java/com/l2jserver/service/database/LoginServerJDBCDatabaseService.java
+++ b/l2jserver2-loginserver/src/main/java/com/l2jserver/service/database/LoginServerJDBCDatabaseService.java
@@ -18,7 +18,6 @@ package com.l2jserver.service.database;
import java.sql.ResultSet;
-import com.google.inject.Injector;
import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.AbstractService.Depends;
@@ -65,33 +64,19 @@ import com.l2jserver.service.core.threading.ThreadService;
ConfigurationService.class, ThreadService.class })
public class LoginServerJDBCDatabaseService extends AbstractJDBCDatabaseService
implements DatabaseService {
- /**
- * The Google Guice {@link Injector}. It is used to get DAO instances.
- */
- @SuppressWarnings("unused")
- private final Injector injector;
-
/**
* @param configService
* the config service
- * @param injector
- * the Guice {@link Injector}
* @param cacheService
* the cache service
* @param threadService
* the thread service
+ * @param daoResolver
+ * the {@link DataAccessObject DAO} resolver
*/
public LoginServerJDBCDatabaseService(ConfigurationService configService,
- Injector injector, CacheService cacheService,
- ThreadService threadService) {
- super(configService, cacheService, threadService);
- this.injector = injector;
- }
-
- @Override
- public , I extends ID> DataAccessObject getDAO(
- Class model) {
- // TODO
- return null;
+ CacheService cacheService, ThreadService threadService,
+ DAOResolver daoResolver) {
+ super(configService, cacheService, threadService, daoResolver);
}
}
diff --git a/pom.xml b/pom.xml
index 7c92f8754..41fd3c6b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,9 +102,18 @@
src/assembly/distribution-mysql5-bin.xml
src/assembly/distribution-h2-bin.xml
+ src/assembly/distribution-orientdb-bin.xml
src/assembly/distribution-src.xml
+
+
+ package
+
+ assembly
+
+
+
@@ -118,6 +127,137 @@
jar
test
+
+
+
+ org.jboss.netty
+ netty
+ 3.2.4.Final
+ runtime
+
+
+
+ com.google.inject
+ guice
+ 3.0
+ jar
+ runtime
+
+
+ com.google.inject.extensions
+ guice-assistedinject
+ 3.0
+ jar
+ runtime
+
+
+ com.google.inject.extensions
+ guice-multibindings
+ 3.0
+ jar
+ runtime
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.6.1
+ jar
+ runtime
+
+
+ org.slf4j
+ jcl-over-slf4j
+ 1.6.1
+ jar
+ runtime
+
+
+
+ mysql
+ mysql-connector-java
+ 5.1.16
+ compile
+
+
+ com.h2database
+ h2
+ 1.3.155
+ compile
+
+
+ commons-dbcp
+ commons-dbcp
+ 1.4
+ jar
+ compile
+
+
+
+ com.orientechnologies
+ orientdb-core
+ 1.0rc5
+ compile
+
+
+
+ net.sf.ehcache
+ ehcache-core
+ 2.4.2
+ jar
+ runtime
+
+
+
+ org.htmlparser
+ htmlparser
+ 2.1
+ jar
+ runtime
+
+
+
+ javolution
+ javolution
+ 5.5.1
+ jar
+ runtime
+
+
+ com.google.guava
+ guava
+ r09
+ jar
+ runtime
+
+
+ commons-io
+ commons-io
+ 2.0.1
+ jar
+ runtime
+
+
+ commons-pool
+ commons-pool
+ 1.5.6
+ jar
+ runtime
+
+
+ commons-collections
+ commons-collections
+ 3.2.1
+ jar
+ runtime
+
+
+ org.apache.commons
+ commons-math
+ 2.2
+ jar
+ runtime
+
@@ -136,8 +276,13 @@
default
- EclipseLink Repo
- http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo
+ orientechnologies-repository
+ Orient Technologies Maven2 Repository
+ http://www.orientechnologies.com/listing/m2
+
+ true
+ always
+