1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-05 23:22:47 +00:00

Implements OrientDB as internal plug-and-play database

This commit is contained in:
2011-12-25 21:13:00 -02:00
parent a55a1d55f6
commit 1a4a4b0fcf
57 changed files with 43925 additions and 41789 deletions

View File

@@ -77,6 +77,7 @@ public class L2JGameServerMain {
}
}
}));
} catch (Exception e) {
System.out.println("GameServer could not be started!");
e.printStackTrace();

View File

@@ -89,8 +89,8 @@ public class ServiceModule extends AbstractModule {
bind(CacheService.class).to(SoftCacheService.class)
.in(Scopes.SINGLETON);
bind(DatabaseService.class).to(GameServerJDBCDatabaseService.class).in(
Scopes.SINGLETON);
bind(DatabaseService.class).to(GameServerJDBCDatabaseService.class)
.in(Scopes.SINGLETON);
bind(WorldIDService.class).to(CachedWorldIDService.class).in(
Scopes.SINGLETON);

View File

@@ -112,7 +112,8 @@ public class GameServerJDBCDatabaseService extends AbstractSQLDatabaseService
}
@Override
protected void ensureDatabaseSchema(Connection conn) throws SQLException, IOException {
protected void ensureDatabaseSchema(Connection conn) throws SQLException,
IOException {
updateSchema(conn, QActorSkill.actorSkill);
updateSchema(conn, QCharacter.character);
updateSchema(conn, QCharacterFriend.characterFriend);
@@ -121,7 +122,7 @@ public class GameServerJDBCDatabaseService extends AbstractSQLDatabaseService
updateSchema(conn, QItem.item);
updateSchema(conn, QLogChat.logChat);
if (updateSchema(conn, QNPC.npc)) {
importSQL(conn, vfsService.resolve("data/sql/npc.sql"));
importData(vfsService.resolve("data/static/npc.csv"), QNPC.npc);
}
}
}

View File

@@ -0,0 +1,102 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database;
import java.io.IOException;
import java.nio.file.Paths;
import com.google.inject.Inject;
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.database.model.QActorSkill;
import com.l2jserver.service.database.model.QCharacter;
import com.l2jserver.service.database.model.QCharacterFriend;
import com.l2jserver.service.database.model.QCharacterShortcut;
import com.l2jserver.service.database.model.QClan;
import com.l2jserver.service.database.model.QItem;
import com.l2jserver.service.database.model.QLogChat;
import com.l2jserver.service.database.model.QNPC;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService;
import com.l2jserver.service.game.template.TemplateService;
/**
* This is an implementation of {@link DatabaseService} that provides an layer
* to OrientDB Object Database.
*
* <h1>Internal specification</h1> <h2>The
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.Query
* Query} object</h2>
*
* If you wish to implement a new {@link DataAccessObject} you should try not
* use
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.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.orientdb.AbstractOrientDatabaseService.InsertQuery
* InsertUpdateQuery} ,
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery
* SelectListQuery} or
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery
* SelectSingleQuery} . If you do need low level access, feel free to use the
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.Query
* Query} class directly.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@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);
}
@Override
protected void ensureDatabaseSchema() {
createSchema(QActorSkill.actorSkill);
createSchema(QCharacter.character);
createSchema(QCharacterFriend.characterFriend);
createSchema(QCharacterShortcut.characterShortcut);
createSchema(QClan.clan);
createSchema(QItem.item);
createSchema(QLogChat.logChat);
if (createSchema(QNPC.npc)) {
try {
importData(Paths.get("data/static/npc.csv"), QNPC.npc);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Scopes;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.dao.CharacterShortcutDAO;
import com.l2jserver.model.dao.ChatMessageDAO;
import com.l2jserver.model.dao.ClanDAO;
import com.l2jserver.model.dao.ItemDAO;
import com.l2jserver.model.dao.NPCDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBCharacterDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBCharacterFriendDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBCharacterShortcutDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBChatMessageDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBClanDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBItemDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBNPCDAO;
/**
* Google Guice {@link Module} for OrientDB DAOs
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBDAOModule extends AbstractModule {
@Override
protected void configure() {
bind(CharacterDAO.class).to(OrientDBCharacterDAO.class).in(
Scopes.SINGLETON);
bind(CharacterFriendDAO.class).to(OrientDBCharacterFriendDAO.class).in(
Scopes.SINGLETON);
bind(CharacterShortcutDAO.class).to(OrientDBCharacterShortcutDAO.class)
.in(Scopes.SINGLETON);
bind(NPCDAO.class).to(OrientDBNPCDAO.class).in(Scopes.SINGLETON);
bind(ItemDAO.class).to(OrientDBItemDAO.class).in(Scopes.SINGLETON);
bind(ClanDAO.class).to(OrientDBClanDAO.class).in(Scopes.SINGLETON);
// logs
bind(ChatMessageDAO.class).to(OrientDBChatMessageDAO.class).in(
Scopes.SINGLETON);
// DAO Resolver
bind(DAOResolver.class).to(GameServerDAOResolver.class).in(
Scopes.SINGLETON);
}
}

View File

@@ -0,0 +1,174 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.id.AccountID;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.world.Clan;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterMapper;
import com.l2jserver.service.database.model.QCharacter;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBCharacterDAO extends
AbstractOrientDBDAO<L2Character, CharacterID> implements CharacterDAO {
/**
* The {@link L2Character} mapper
*/
private final CharacterMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the character mapper
*/
@Inject
public OrientDBCharacterDAO(DatabaseService database, CharacterMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public L2Character select(final CharacterID id) {
return database
.query(new SelectSingleQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.characterId)).eq(
id.getID());
}
});
}
@Override
public void load(final Clan clan) {
clan.getMembers()
.load(database
.query(new SelectListQuery<CharacterID, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper
.getIDMapper(QCharacter.character)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.clanId)).eq(
clan.getID().getID());
}
}));
}
@Override
public L2Character selectByName(final String name) {
return database
.query(new SelectSingleQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.name)).eq(name);
}
});
}
@Override
public List<L2Character> selectByAccount(final AccountID account) {
return database
.query(new SelectListQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.accountId)).eq(
account.getID());
}
});
}
@Override
public List<CharacterID> selectIDs() {
return database
.query(new SelectListQuery<CharacterID, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper
.getIDMapper(QCharacter.character)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record;
}
});
}
@Override
public int insertObjects(L2Character... characters) {
return database
.query(new InsertQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper, characters));
}
@Override
public int updateObjects(L2Character... characters) {
return database.query(new UpdateQuery<L2Character, QCharacter>(
QCharacter.character, mapper, characters) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
L2Character o) {
return record.field(name(e.characterId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(L2Character... characters) {
return database.query(new DeleteQuery<L2Character, QCharacter>(
QCharacter.character, characters) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
L2Character o) {
return record.field(name(e.characterId)).eq(o.getID().getID());
}
});
}
@Override
protected L2Character[] wrap(Model<?>... objects) {
final L2Character[] array = new L2Character[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (L2Character) object;
}
return array;
}
}

View File

@@ -0,0 +1,166 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.game.CharacterFriend;
import com.l2jserver.model.id.FriendID;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterFriendList;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterFriendMapper;
import com.l2jserver.service.database.model.QCharacterFriend;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterFriendDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBCharacterFriendDAO extends
AbstractOrientDBDAO<CharacterFriend, FriendID> implements
CharacterFriendDAO {
/**
* The {@link CharacterFriend} mapper
*/
private final CharacterFriendMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the character friend mapper
*/
@Inject
public OrientDBCharacterFriendDAO(DatabaseService database,
CharacterFriendMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public CharacterFriend select(final FriendID id) {
return database
.query(new SelectSingleQuery<CharacterFriend, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterFriend e) {
return record.field(name(e.characterId))
.eq(id.getCharacterID().getID())
.field(name(e.characterIdFriend))
.eq(id.getFriendID());
}
});
}
@Override
public void load(final L2Character character) {
final List<CharacterFriend> list = database
.query(new SelectListQuery<CharacterFriend, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterFriend e) {
return record.field(name(e.characterId)).eq(
character.getID().getID());
}
});
character.getFriendList().load(list);
}
@Override
public List<FriendID> selectIDs() {
return database
.query(new SelectListQuery<FriendID, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper
.getIDMapper(QCharacterFriend.characterFriend)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterFriend e) {
return record;
}
});
}
@Override
public int insertObjects(CharacterFriend... friends) {
return database
.query(new InsertQuery<CharacterFriend, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper, friends));
}
@Override
public int updateObjects(CharacterFriend... friends) {
// it is not possible update friend objects, because they are only a ID
// pair and IDs are immutable
return 0;
}
@Override
public int deleteObjects(CharacterFriend... friends) {
return database
.query(new DeleteQuery<CharacterFriend, QCharacterFriend>(
QCharacterFriend.characterFriend, friends) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, CharacterFriend friend) {
return record.field(name(e.characterId))
.eq(friend.getID().getCharacterID().getID())
.field(name(e.characterIdFriend))
.eq(friend.getID().getFriendID());
}
});
}
@Override
public boolean save(final CharacterFriendList friends) {
for (final CharacterFriend friend : friends) {
if (save(friend) == 0)
return false;
}
return true;
}
@Override
public boolean delete(final CharacterFriendList friends) {
for (final CharacterFriend friend : friends) {
if (deleteObjects(friend) == 0)
return false;
}
return true;
}
@Override
protected CharacterFriend[] wrap(Model<?>... objects) {
final CharacterFriend[] array = new CharacterFriend[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (CharacterFriend) object;
}
return array;
}
}

View File

@@ -0,0 +1,149 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.dao.CharacterShortcutDAO;
import com.l2jserver.model.game.CharacterShortcut;
import com.l2jserver.model.id.CharacterShortcutID;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterShortcutMapper;
import com.l2jserver.service.database.model.QCharacterShortcut;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterFriendDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBCharacterShortcutDAO extends
AbstractOrientDBDAO<CharacterShortcut, CharacterShortcutID> implements
CharacterShortcutDAO {
private final CharacterShortcutMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the {@link CharacterShortcut} mapper
*/
@Inject
public OrientDBCharacterShortcutDAO(DatabaseService database,
CharacterShortcutMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public CharacterShortcut select(final CharacterShortcutID id) {
return database
.query(new SelectSingleQuery<CharacterShortcut, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterShortcut e) {
return record.field(name(e.shortcutId)).eq(id.getID());
}
});
}
@Override
public List<CharacterShortcut> selectByCharacter(final L2Character character) {
return database
.query(new SelectListQuery<CharacterShortcut, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterShortcut e) {
return record.field(name(e.characterId)).eq(
character.getID().getID());
}
});
}
@Override
public List<CharacterShortcutID> selectIDs() {
return database
.query(new SelectListQuery<CharacterShortcutID, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut,
mapper.getIDMapper(QCharacterShortcut.characterShortcut)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterShortcut e) {
return record;
}
});
}
@Override
public int insertObjects(CharacterShortcut... shortcuts) {
return database
.query(new InsertQuery<CharacterShortcut, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper,
QCharacterShortcut.characterShortcut.shortcutId,
shortcuts));
}
@Override
public int updateObjects(CharacterShortcut... shortcuts) {
return database
.query(new UpdateQuery<CharacterShortcut, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper, shortcuts) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, CharacterShortcut o) {
return record.field(name(e.shortcutId)).eq(
o.getID().getID());
}
});
}
@Override
public int deleteObjects(CharacterShortcut... shortcuts) {
return database
.query(new DeleteQuery<CharacterShortcut, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, shortcuts) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, CharacterShortcut o) {
return record.field(name(e.shortcutId)).eq(
o.getID().getID());
}
});
}
@Override
protected CharacterShortcut[] wrap(Model<?>... objects) {
final CharacterShortcut[] array = new CharacterShortcut[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (CharacterShortcut) object;
}
return array;
}
}

View File

@@ -0,0 +1,120 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.Collection;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.ChatMessageDAO;
import com.l2jserver.model.id.ChatMessageID;
import com.l2jserver.model.server.ChatMessage;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.ChatMessageMapper;
import com.l2jserver.service.database.model.QLogChat;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBChatMessageDAO extends
AbstractOrientDBDAO<ChatMessage, ChatMessageID> implements
ChatMessageDAO {
private final ChatMessageMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBChatMessageDAO(DatabaseService database,
ChatMessageMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public ChatMessage select(final ChatMessageID id) {
return database
.query(new SelectSingleQuery<ChatMessage, Integer, ChatMessageID, QLogChat>(
QLogChat.logChat, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QLogChat e) {
return record.field(name(e.messageId)).eq(id.getID());
}
});
}
@Override
public Collection<ChatMessageID> selectIDs() {
return database
.query(new SelectListQuery<ChatMessageID, Integer, ChatMessageID, QLogChat>(
QLogChat.logChat, mapper.getIDMapper(QLogChat.logChat)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QLogChat e) {
return record;
}
});
}
@Override
public int insertObjects(ChatMessage... objects) {
return database
.query(new InsertQuery<ChatMessage, Integer, ChatMessageID, QLogChat>(
QLogChat.logChat, mapper, QLogChat.logChat.messageId,
objects));
}
@Override
public int updateObjects(ChatMessage... objects) {
return 0;
}
@Override
public int deleteObjects(ChatMessage... objects) {
return database.query(new DeleteQuery<ChatMessage, QLogChat>(
QLogChat.logChat, objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
ChatMessage o) {
return record.field(name(e.messageId)).eq(o.getID().getID());
}
});
}
@Override
protected ChatMessage[] wrap(Model<?>... objects) {
final ChatMessage[] array = new ChatMessage[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (ChatMessage) object;
}
return array;
}
}

View File

@@ -0,0 +1,123 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.Collection;
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.id.object.ClanID;
import com.l2jserver.model.world.Clan;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.ClanMapper;
import com.l2jserver.service.database.model.QClan;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBClanDAO extends AbstractOrientDBDAO<Clan, ClanID> implements ClanDAO {
private final ClanMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBClanDAO(DatabaseService database, final ClanMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public Clan select(final ClanID id) {
return database
.query(new SelectSingleQuery<Clan, Integer, ClanID, QClan>(
QClan.clan, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QClan e) {
return record.field(name(e.clanId)).eq(id.getID());
}
});
}
@Override
public Collection<ClanID> selectIDs() {
return database
.query(new SelectListQuery<ClanID, Integer, ClanID, QClan>(
QClan.clan, mapper.getIDMapper(QClan.clan)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QClan e) {
return record;
}
});
}
@Override
public int insertObjects(Clan... objects) {
return database.query(new InsertQuery<Clan, Integer, ClanID, QClan>(
QClan.clan, mapper, QClan.clan.clanId, objects));
}
@Override
public int updateObjects(Clan... objects) {
return database.query(new UpdateQuery<Clan, QClan>(QClan.clan, mapper,
objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
Clan o) {
return record.field(name(e.clanId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(Clan... objects) {
return database
.query(new DeleteQuery<Clan, QClan>(QClan.clan, objects) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, Clan o) {
return record.field(name(e.clanId)).eq(o.getID().getID());
}
});
}
@Override
protected Clan[] wrap(Model<?>... objects) {
final Clan[] array = new Clan[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (Clan) object;
}
return array;
}
}

View File

@@ -0,0 +1,154 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.Collection;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.ItemDAO;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.ItemMapper;
import com.l2jserver.service.database.model.QItem;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link ItemDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBItemDAO extends AbstractOrientDBDAO<Item, ItemID>
implements ItemDAO {
private final ItemMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBItemDAO(DatabaseService database, ItemMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public Item select(final ItemID id) {
return database
.query(new SelectSingleQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record.field(name(e.itemId)).eq(id.getID());
}
});
}
@Override
public List<Item> selectByCharacter(final L2Character character) {
return database
.query(new SelectListQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record.field(name(e.characterId)).eq(
character.getID().getID());
}
});
}
@Override
public List<Item> selectDroppedItems() {
return database
.query(new SelectListQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record.field(name(e.itemId)).eq(
ItemLocation.GROUND);
}
});
}
@Override
public Collection<ItemID> selectIDs() {
return database
.query(new SelectListQuery<ItemID, Integer, ItemID, QItem>(
QItem.item, mapper.getIDMapper(QItem.item)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record;
}
});
}
@Override
public int insertObjects(Item... objects) {
return database.query(new InsertQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper, objects));
}
@Override
public int updateObjects(Item... objects) {
return database.query(new UpdateQuery<Item, QItem>(QItem.item, mapper,
objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
Item o) {
return record.field(name(e.itemId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(Item... objects) {
return database
.query(new DeleteQuery<Item, QItem>(QItem.item, objects) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, Item o) {
return record.field(name(e.itemId)).eq(o.getID().getID());
}
});
}
@Override
protected Item[] wrap(Model<?>... objects) {
final Item[] array = new Item[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (Item) object;
}
return array;
}
}

View File

@@ -0,0 +1,148 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao.orientdb;
import java.util.Collection;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.NPCDAO;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.world.NPC;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.NPCMapper;
import com.l2jserver.service.database.model.QNPC;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBNPCDAO extends AbstractOrientDBDAO<NPC, NPCID> implements
NPCDAO {
private final NPCMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBNPCDAO(DatabaseService database, NPCMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public NPC select(final NPCID id) {
return database.query(new SelectSingleQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return record.field(name(e.npcId)).eq(id.getID());
}
});
}
@Override
public Collection<NPC> loadAll() {
return database.query(new SelectListQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return null;
}
});
}
@Override
public List<NPC> selectByTemplate(final NPCTemplateID templateID) {
return database.query(new SelectListQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return record.field(name(e.npcTemplateId)).eq(
templateID.getID());
}
});
}
@Override
public Collection<NPCID> selectIDs() {
return database.query(new SelectListQuery<NPCID, Integer, NPCID, QNPC>(
QNPC.npc, mapper.getIDMapper(QNPC.npc)) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return record;
}
});
}
@Override
public int insertObjects(NPC... objects) {
return database.query(new InsertQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper, objects));
}
@Override
public int updateObjects(NPC... objects) {
return database.query(new UpdateQuery<NPC, QNPC>(QNPC.npc, mapper,
objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
NPC o) {
return record.field(name(e.npcId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(NPC... objects) {
return database.query(new DeleteQuery<NPC, QNPC>(QNPC.npc, objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
NPC o) {
return record.field(name(e.npcId)).eq(o.getID().getID());
}
});
}
@Override
protected NPC[] wrap(Model<?>... objects) {
final NPC[] array = new NPC[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (NPC) object;
}
return array;
}
}

View File

@@ -34,30 +34,6 @@ import com.l2jserver.service.database.model.QCharacterFriend;
*/
public class CharacterFriendMapper extends
AbstractMapper<CharacterFriend, FriendID, FriendID, QCharacterFriend> {
// private final CompoundPrimaryKeyMapper<FriendID, CharacterID,
// CharacterID, QCharacterFriend> idMapper = new
// CompoundPrimaryKeyMapper<FriendID, CharacterID, CharacterID,
// QCharacterFriend>() {
// @Override
// public AbstractCompoundID<CharacterID, CharacterID> raw(
// QCharacterFriend entity, DatabaseRow row) {
// return createID(entity, row);
// }
//
// @Override
// public FriendID createID(QCharacterFriend entity, DatabaseRow row) {
// return idProvider.createID(
// charIdProvider.resolveID(row.get(e.characterId)),
// charIdProvider.resolveID(row.get(e.characterIdFriend)));
// }
//
// @Override
// public FriendID generated(
// AbstractCompoundID<CharacterID, CharacterID> raw) {
// return null;
// }
// };
/**
* The {@link CharacterID} provider
*/

View File

@@ -75,6 +75,7 @@ public class NPCMapper extends AbstractMapper<NPC, Integer, NPCID, QNPC> {
@Override
public NPC select(QNPC e, DatabaseRow row) {
final NPCID id = idProvider.resolveID(row.get(e.npcId));
NPCTemplateID templateId = templateIdProvider.resolveID(row
.get(e.npcTemplateId));
NPCTemplate template = templateId.getTemplate();

View File

@@ -3,7 +3,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.Skill;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;

View File

@@ -5,13 +5,11 @@ import static com.mysema.query.types.PathMetadataFactory.forVariable;
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.character.CharacterAppearance.CharacterFace;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.mysema.query.sql.ForeignKey;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;
@@ -82,7 +80,7 @@ public class QCharacter extends RelationalPathBase<Integer> {
"apperance_face", CharacterFace.class);
public final PrimaryKey<Integer> primary = createPrimaryKey(characterId);
public final ForeignKey<Clan> clanIdKey = createForeignKey(clanId, "");
//public final ForeignKey<Clan> clanIdKey = createForeignKey(clanId, "");
public QCharacter(String variable) {
super(Integer.class, forVariable(variable), "null", "character");

View File

@@ -3,7 +3,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.id.FriendID;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -3,9 +3,9 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -2,7 +2,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -4,9 +4,9 @@ import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnDefault;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnDefault;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -4,9 +4,9 @@ import static com.mysema.query.types.PathMetadataFactory.forVariable;
import java.util.Date;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.l2jserver.service.game.chat.ChatMessageType;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;

View File

@@ -2,7 +2,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -152,6 +152,7 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
for (final NPC npc : npcs) {
spawnService.spawn(npc, null);
}
log.info("Loaded {} NPC instances", npcs.size());
} catch (SpawnPointNotFoundServiceException e) {
throw new ServiceStartException(e);
} catch (AlreadySpawnedServiceException e) {