Source Code Cross Referenced for UniverseServer.java in  » 6.0-JDK-Modules » java-3d » com » db » server » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » com.db.server 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:/*
0002: * Copyright (c) 2001 Silvere Martin-Michiellot All Rights Reserved.
0003: *
0004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
0005: * royalty free, license to use, modify and redistribute this 
0006: * software in source and binary code form,
0007: * provided that i) this  copyright notice and license appear on all copies of
0008: * the software; and ii) Licensee does not utilize the software in a manner
0009: * which is disparaging to Silvere Martin-Michiellot.
0010: *
0011: * This software is provided "AS IS," without a warranty of any kind. ALL
0012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
0013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
0014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
0015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
0016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
0017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
0018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
0019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
0020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
0021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
0022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
0023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
0024: *
0025: * This software is not designed or intended for use in on-line control of
0026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
0027: * the design, construction, operation or maintenance of any nuclear
0028: * facility. Licensee represents and warrants that it will not use or
0029: * redistribute the Software for such purposes.
0030: *
0031: * @Author: Silvere Martin-Michiellot
0032: *
0033: */
0034:
0035:package com.db.server;
0036:
0037:
0038:import com.db.client.ServerHelper;
0039:import com.db.net.*;
0040:
0041:import java.io.*;
0042:import java.lang.IllegalArgumentException;
0043:import java.net.*;
0044:import java.security.*;
0045:import java.util.*;
0046:import java.util.zip.*;
0047:import javax.jdo.*;
0048:import javax.media.j3d.*;
0049:import javax.vecmath.*;
0050:import javax.net.*;
0051:import javax.net.ssl.*;
0052:import com.sun.net.ssl.*;
0053:
0054://import com.sun.jdori.*;
0055://import com.sun.jdori.common.*;
0056:
0057:
0058:import com.sun.j3d.utils.scenegraph.io.*;
0059:
0060:/**
0061: * This is the black box of the server side. It provides network and database capabilities but no GUI interface.
0062: */
0063:
0064:Quetzalcoatl (aztec god, brother of Tezcatlipoca)
0065:Viracocha (inca god)
0066:Itzamna (maya god)
0067:
0068:public class UniverseServer extends Object implements  Runnable {
0069:    
0070:    /**
0071:     * IP
0072:     * Port
0073:     * information (if a virtual world is to be described using World Spots on different servers, the informations should always
0074:     * be the same):
0075:     * Date
0076:     * Creator author Name, E-mail, Public Key
0077:     * Given name for Universe
0078:     * Version
0079:     * local World Spot list (stored using a database)
0080:     * server list:
0081:     * servers of connected World Spots
0082:     * IP
0083:     * Port
0084:     * remote World Spot list information:
0085:     * position and orientation
0086:     * encompass
0087:     * informations
0088:     * ruler
0089:     * gates to other known virtual worlds
0090:     * IP
0091:     * Port
0092:     * current time relative to Greenwich Mean Time (should be as accurate as possible) (used to compute timers) (your favorite
0093:     * watch might actually show you what it wants)
0094:     */
0095:    
0096:    private static final String SECURED = "TLS";
0097:    private static final String PLAINSOCKET = "PlainSocket";
0098:    private static final boolean clientAuthentification = true;
0099:    private static int connectionQueue = 50;
0100:    public static int DefaultServerPort = 7777;
0101:    
0102:    private ServerSocket serverSocket;
0103:    
0104:    //private FOStorePMF fOStorePMF;
0105:    private PersistenceManager persistenceManager;
0106:    
0107:    public final static String STRING_DATE = "Date";
0108:    public final static String STRING_CREATOR_NAME = "Creator Name";
0109:    public final static String STRING_CREATOR_E_MAIL = "Creator e-mail";
0110:    public final static String STRING_CREATOR_PUBLIC_KEY = "Creator Public Key";
0111:    public final static String STRING_NAME = "Name";
0112:    public final static String STRING_VERSION = "Version";
0113:    
0114:    private LoginInformation loginInformation;
0115:    private InetAddress IP;
0116:    private int port;
0117:    private Hashtable information;
0118:    private HashSet localWorldSpots;
0119:    private HashSet remoteServers;
0120:    private HashSet gates;
0121:    private long time;
0122:    private long offset;
0123:    private boolean activeLog;
0124:    
0125:    public UniverseServer() {
0126:        
0127:        throw new java.lang.IllegalArgumentException("A universe server must have a login, a password and at least a WorldSpot.");
0128:        
0129:    }
0130:    
0131:    public UniverseServer(LoginInformation loginInformation, WorldSpot worldSpot) throws IOException {
0132:        
0133:        this (loginInformation, InetAddress.getLocalHost(), UniverseServer.DefaultServerPort, worldSpot);
0134:        
0135:    }
0136:    
0137:    public UniverseServer(LoginInformation loginInformation, InetAddress inetAddress, WorldSpot worldSpot) throws IOException {
0138:        
0139:        this (loginInformation, inetAddress, UniverseServer.DefaultServerPort, worldSpot);
0140:        
0141:    }
0142:    
0143:    public UniverseServer(LoginInformation loginInformation, InetAddress inetAddress, int port, WorldSpot worldSpot) throws IOException {
0144:        
0145:        ServerSocketFactory serverSocketFactory;
0146:        Avatar ruler;
0147:        
0148:        activeLog = false;
0149:        
0150:        this .loginInformation = loginInformation;
0151:        
0152:        ruler = this .createRuler(loginInformation);
0153:        
0154:        this .IP = inetAddress;
0155:        this .port = port;
0156:        
0157:        //database part
0158:        
0159:        //fOStorePMF = new FOStorePMF();
0160:        //YYYYYYYYYYYYYYYYY
0161:        //persistenceManager = PersistenceManagerFactory.getPersistenceManager();
0162:        this .addLocalWorldSpot(worldSpot);
0163:        
0164:        //Network part
0165:       // try {
0166:            serverSocketFactory = this .getServerSocketFactory(UniverseServer.PLAINSOCKET);
0167:            serverSocket = serverSocketFactory.createServerSocket(port, connectionQueue, IP);
0168:            
0169:            if (clientAuthentification) {
0170:                ((SSLServerSocket)serverSocket).setNeedClientAuth(true);
0171:            }
0172:            this .newListener();
0173:            
0174:        //} catch (IOException iOException) {
0175:        //    System.out.println("Unable to start Server: " +
0176:        //    iOException.getMessage());
0177:        //    iOException.printStackTrace();
0178:        //}
0179:        
0180:    }
0181:    
0182:    public final PersistenceManager getPersistenceManager() {
0183:        
0184:        return this .persistenceManager;
0185:        
0186:    }
0187:    
0188:    
0189:    //can be called by any requesting application (may be not related directly to digital biosphere company)
0190:    public final InetAddress getIP() {
0191:        
0192:        return this .IP;
0193:        
0194:    }
0195:    
0196:    //at start-up time only
0197:    //should use local IP
0198:    //but there may be physical machines with mutiple IP so this parameter
0199:    protected final void setIP(InetAddress IP) {
0200:        
0201:        this .IP = IP;
0202:        
0203:    }
0204:    
0205:    public final int getPort() {
0206:        
0207:        return this .port;
0208:        
0209:    }
0210:    
0211:    //at start-up time only
0212:    public final void setPort(int port) {
0213:        
0214:        this .port = port;
0215:        
0216:    }
0217:    
0218:    public final LoginInformation getLoginInformation() {
0219:        
0220:        return this .loginInformation;
0221:        
0222:    }
0223:    
0224:    protected final void setLoginInformation(LoginInformation loginInformation) {
0225:        
0226:        this .loginInformation = loginInformation;
0227:        
0228:    }
0229:    
0230:    public final Hashtable getInformation() {
0231:        
0232:        information.put(UniverseServer.STRING_DATE, this .getDate());
0233:        information.put(UniverseServer.STRING_CREATOR_NAME, this .getCreatorName());
0234:        information.put(UniverseServer.STRING_CREATOR_E_MAIL, this .getCreatorEMail());
0235:        information.put(UniverseServer.STRING_CREATOR_PUBLIC_KEY, this .getCreatorPublicKey());
0236:        information.put(UniverseServer.STRING_NAME, this .getName());
0237:        information.put(UniverseServer.STRING_VERSION, this .getVersion());
0238:        
0239:        return information;
0240:        
0241:    }
0242:    
0243:    public final Object getInformation(String key) {
0244:        
0245:        return information.get(key);
0246:        
0247:    }
0248:    
0249:    public final Date getDate() {
0250:        
0251:        return (Date)this .getInformation(UniverseServer.STRING_DATE);
0252:        
0253:    }
0254:    
0255:    public final String getCreatorName() {
0256:        
0257:        return (String)this .getInformation(UniverseServer.STRING_CREATOR_NAME);
0258:        
0259:    }
0260:    
0261:    public final String getCreatorEMail() {
0262:        
0263:        return (String)this .getInformation(UniverseServer.STRING_CREATOR_E_MAIL);
0264:        
0265:    }
0266:    
0267:    public final PublicKey getCreatorPublicKey() {
0268:        
0269:        return (PublicKey)this .getInformation(UniverseServer.STRING_CREATOR_PUBLIC_KEY);
0270:        
0271:    }
0272:    
0273:    public final String getName() {
0274:        
0275:        return (String)this .getInformation(UniverseServer.STRING_NAME);
0276:        
0277:    }
0278:    
0279:    public final String getVersion() {
0280:        
0281:        return (String)this .getInformation(UniverseServer.STRING_VERSION);
0282:        
0283:    }
0284:    
0285:    //asynchronous modification while server running via a GUI side track tool
0286:    public final void setDate(Date date) {
0287:        
0288:        this .addInformation(UniverseServer.STRING_DATE, date.toString());
0289:        
0290:    }
0291:    
0292:    //asynchronous modification while server running via a GUI side track tool
0293:    public final void setCreatorName(String name) {
0294:        
0295:        this .addInformation(UniverseServer.STRING_CREATOR_NAME, name);
0296:        
0297:    }
0298:    
0299:    //asynchronous modification while server running via a GUI side track tool
0300:    public final void setCreatorEMail(String eMail) {
0301:        
0302:        this .addInformation(UniverseServer.STRING_CREATOR_E_MAIL, eMail);
0303:        
0304:    }
0305:    
0306:    //asynchronous modification while server running via a GUI side track tool
0307:    public final void setCreatorPublicKey(PublicKey publicKey) {
0308:        
0309:        this .addInformation(UniverseServer.STRING_CREATOR_PUBLIC_KEY, publicKey.toString());
0310:        
0311:    }
0312:    
0313:    //asynchronous modification while server running via a GUI side track tool
0314:    public final void setName(String name) {
0315:        
0316:        this .addInformation(UniverseServer.STRING_NAME, name);
0317:        
0318:    }
0319:    
0320:    //asynchronous modification while server running via a GUI side track tool
0321:    public final void setVersion(String version) {
0322:        
0323:        this .addInformation(UniverseServer.STRING_VERSION, version);
0324:        
0325:    }
0326:    
0327:    //asynchronous modification while server running via a GUI side track tool
0328:    //obliterates every previously stored information including reserved fields
0329:    //no check for valid values are made, please be cautious
0330:    public final void setInformation(Hashtable information) {
0331:        
0332:        this .information = information;
0333:        
0334:    }
0335:    
0336:    //asynchronous addition while server running via a GUI side track tool
0337:    //use the corresponding method to set the individual default fields
0338:    public final void addInformation(String key, String keyValue) {
0339:        
0340:        //check if it is a reserved field or not
0341:        if ((key!=UniverseServer.STRING_DATE) && (key!=UniverseServer.STRING_CREATOR_NAME) && (key!=UniverseServer.STRING_CREATOR_E_MAIL) && (key!=UniverseServer.STRING_CREATOR_PUBLIC_KEY) && (key!=UniverseServer.STRING_NAME) && (key!=UniverseServer.STRING_VERSION)) {
0342:            this .information.put(key, keyValue);
0343:        }
0344:        else {
0345:            throw new java.lang.IllegalArgumentException("You can't add directely Information on the restricted fields.");
0346:        }
0347:        
0348:    }
0349:    
0350:    //asynchronous deletion while server running via a GUI side track tool
0351:    public final void removeInformation(String key) {
0352:        
0353:        //check if it is a reserved field or not
0354:        if ((key!=UniverseServer.STRING_DATE) && (key!=UniverseServer.STRING_CREATOR_NAME) && (key!=UniverseServer.STRING_CREATOR_E_MAIL) && (key!=UniverseServer.STRING_CREATOR_PUBLIC_KEY) && (key!=UniverseServer.STRING_NAME) && (key!=UniverseServer.STRING_VERSION)) {
0355:            this .information.remove(key);
0356:        }
0357:        else {
0358:            throw new java.lang.IllegalArgumentException("You can't remove directely Information on the restricted fields.");
0359:        }
0360:        
0361:    }
0362:    
0363:    public final HashSet getLocalWorldSpots() {
0364:        
0365:        Transaction transaction;
0366:        Extent extent;
0367:        Query query;
0368:        HashSet hashSet;
0369:        
0370:        try {
0371:            transaction = this .getPersistenceManager().currentTransaction();
0372:            transaction.begin();
0373:            
0374:            extent = this .getPersistenceManager().getExtent(WorldSpot.class, true);
0375:            query = this .getPersistenceManager().newQuery(WorldSpot.class, extent);
0376:            hashSet = (HashSet) query.execute();
0377:            
0378:            transaction.commit();
0379:            
0380:            return hashSet;
0381:            
0382:        }
0383:        catch (Exception exception) {
0384:            
0385:            return null;
0386:            
0387:        }
0388:        
0389:    }
0390:    
0391:    //asynchronous addition while server running via a GUI side track tool
0392:    //we check bounds are exclusive but not that the new bounds are continuous with the current WorldSpots
0393:    //we don't check that the resulting bounds on this server are mutually exclusive with remote servers serving the same virtual world
0394:    //proposed ruler must be a new Avatar
0395:    public final void addLocalWorldSpot(WorldSpot worldSpot) {
0396:        
0397:        Transaction transaction;
0398:        Extent extent;
0399:        Query query;
0400:        String filter;
0401:        Collection collection;
0402:        BoundingPolytope currentBounds;
0403:        WorldSpot currentWorldSpot;
0404:        Iterator iterator;
0405:        
0406:        if (worldSpot!=null) {
0407:            
0408:            try {
0409:                transaction = this .getPersistenceManager().currentTransaction();
0410:                transaction.begin();
0411:                
0412:                extent = this .getPersistenceManager().getExtent(WorldSpot.class, true);
0413:                filter = new String("SELECT * FROM WorldSpot");
0414:                query = this .getPersistenceManager().newQuery(WorldSpot.class, extent, filter);
0415:                collection = (Collection) query.execute();
0416:                
0417:                transaction.commit();
0418:                
0419:                iterator = collection.iterator();
0420:                currentBounds = new BoundingPolytope();
0421:                
0422:                while (iterator.hasNext()) {
0423:                    currentWorldSpot = (WorldSpot) iterator.next();
0424:                    currentBounds.combine(currentWorldSpot.getBounds());
0425:                }
0426:                
0427:                if (!currentBounds.intersect(worldSpot.getBounds())) {
0428:                    
0429:                    try {
0430:                        transaction = this .getPersistenceManager().currentTransaction();
0431:                        transaction.begin();
0432:                        
0433:                        extent = this .getPersistenceManager().getExtent(Avatar.class, true);
0434:                        filter = new String("SELECT * FROM Avatar WHERE avatar=worldSpot.getRuler()");
0435:                        query = this .getPersistenceManager().newQuery(Avatar.class, extent, filter);
0436:                        collection = (Collection) query.execute();
0437:                        
0438:                        transaction.commit();
0439:                    }
0440:                    catch (Exception exception) {
0441:                    }
0442:                    
0443:                    if (collection.size()>0) {
0444:                        
0445:                        transaction = this .getPersistenceManager().currentTransaction();
0446:                        transaction.begin();
0447:                        
0448:                        this .getPersistenceManager().makePersistent(worldSpot.getRuler());
0449:                        
0450:                        transaction.commit();
0451:                    }
0452:                    
0453:                    try {
0454:                        transaction = this .getPersistenceManager().currentTransaction();
0455:                        transaction.begin();
0456:                        
0457:                        this .getPersistenceManager().makePersistent(worldSpot);
0458:                        
0459:                        transaction.commit();
0460:                    }
0461:                    catch (Exception exception) {
0462:                    }
0463:                    
0464:                }
0465:                
0466:            }
0467:            catch (Exception exception) {
0468:            }
0469:            
0470:        }
0471:        
0472:    }
0473:    
0474:    //users should be kicked off before the World Spot is permanently removed
0475:    //asynchronous deletion while server running via a GUI side track tool
0476:    public final void removeLocalWorldSpot(WorldSpot worldSpot) {
0477:        
0478:        Transaction transaction;
0479:        Extent extent;
0480:        Query query;
0481:        String filter;
0482:        Collection collection;
0483:        Collection avatars;
0484:        Iterator iterator;
0485:        Avatar avatar;
0486:        
0487:        if (worldSpot!=null) {
0488:            
0489:            avatars = worldSpot.getAvatars(worldSpot.getRuler());
0490:            
0491:            iterator = avatars.iterator();
0492:            while (iterator.hasNext()) {
0493:                avatar = (Avatar) iterator.next();
0494:                avatar.disconnectUser();
0495:            }
0496:            
0497:            try {
0498:                transaction = this .getPersistenceManager().currentTransaction();
0499:                transaction.begin();
0500:                
0501:                extent = this .getPersistenceManager().getExtent(VirtualElement.class, true);
0502:                filter = new String("SELECT * FROM VirtualElement");
0503:                query = this .getPersistenceManager().newQuery(VirtualElement.class, extent, filter);
0504:                collection = (Collection) query.execute();
0505:                
0506:                transaction.commit();
0507:                
0508:                try {
0509:                    transaction = this .getPersistenceManager().currentTransaction();
0510:                    transaction.begin();
0511:                    
0512:                    this .getPersistenceManager().deletePersistentAll(collection);
0513:                    this .getPersistenceManager().deletePersistent(worldSpot);
0514:                    
0515:                    transaction.commit();
0516:                }
0517:                catch (Exception exception) {
0518:                }
0519:                
0520:            }
0521:            catch (Exception exception) {
0522:            }
0523:            
0524:        }
0525:        
0526:    }
0527:    
0528:    //removes existing then set new
0529:    public final void setLocalWorldSpots(HashSet worldSpots) {
0530:        
0531:        Iterator iterator;
0532:        
0533:        iterator = this .getLocalWorldSpots().iterator();
0534:        while (iterator.hasNext()) {
0535:            this .removeLocalWorldSpot((WorldSpot)iterator.next());
0536:        }
0537:        
0538:        iterator = worldSpots.iterator();
0539:        while (iterator.hasNext()) {
0540:            this .addLocalWorldSpot((WorldSpot)iterator.next());
0541:        }
0542:                
0543:    }
0544:    
0545:    //callback from worldspot when bounds have changed
0546:    protected void notifyBoundsChange(WorldSpot worldSpot) {
0547:        
0548:        this .notifyLocalWorldSpotUpdate();
0549:        
0550:    }
0551:    
0552:    //tell to remote servers that the local world spot list is updated
0553:    public final void notifyLocalWorldSpotUpdate() {
0554:        
0555:        Socket socket;
0556:        ObjectOutputStream objectOutputStream;
0557:        
0558:        HashSet hashSet;
0559:        ControlNotification controlNotification;
0560:        WorldSpot worldSpot;
0561:        WorldSpotBasicInformation worldSpotBasicInformation;
0562:        RemoteWorldSpotsAccess remoteWorldSpotsAccess;
0563:        Iterator iterator;
0564:        
0565:        hashSet = new HashSet();
0566:        
0567:        iterator = this .getLocalWorldSpots().iterator();
0568:        while (iterator.hasNext()) {
0569:            worldSpot = (WorldSpot) iterator.next();
0570:            worldSpotBasicInformation = new WorldSpotBasicInformation(worldSpot.getRuler(), worldSpot.getBounds(), worldSpot.getInformation());
0571:            hashSet.add(worldSpotBasicInformation);
0572:        }
0573:        
0574:        iterator = this .getRemoteServers().iterator();
0575:        while (iterator.hasNext()) {
0576:            //query distant server and fetch informations
0577:            //distant server should send information to update
0578:            remoteWorldSpotsAccess = (RemoteWorldSpotsAccess)iterator.next();
0579:            
0580:            //query distant server and fetch informations
0581:            try {
0582:                
0583:                socket = new Socket(this .getIP(), this .getPort(), remoteWorldSpotsAccess.getIP(), remoteWorldSpotsAccess.getPort());
0584:                
0585:                objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
0586:                
0587:                controlNotification = new ControlNotification(ControlNotification.LOCALWORLDSPOTS, hashSet);
0588:                // send request
0589:                objectOutputStream.writeObject(controlNotification);
0590:                
0591:                objectOutputStream.flush();
0592:                objectOutputStream.close();
0593:                
0594:                socket.close();
0595:                
0596:            }
0597:            catch (IOException iOexception) {
0598:            }
0599:        }
0600:        
0601:    }
0602:    
0603:    public final HashSet getRemoteServers() {
0604:        
0605:        return this .remoteServers;
0606:        
0607:    }
0608:    
0609:    //asynchronous addition while server running via a GUI side track tool
0610:    public final void setRemoteServers(HashSet remoteServers) {
0611:        
0612:        this .remoteServers = remoteServers;
0613:        
0614:    }
0615:    
0616:    //asynchronous addition while server running via a GUI side track tool
0617:    public final void addRemoteServer(RemoteWorldSpotsAccess remoteWorldSpotsAccess) {
0618:        
0619:        this .remoteServers.add(remoteWorldSpotsAccess);
0620:        
0621:    }
0622:    
0623:    //asynchronous deletion while server running via a GUI side track tool
0624:    public final void removeRemoteServer(RemoteWorldSpotsAccess remoteWorldSpotsAccess) {
0625:        
0626:        this .remoteServers.remove(remoteWorldSpotsAccess);
0627:        
0628:    }
0629:    
0630:    //Queries the servers to be sure they still serve some WorldSpots
0631:    //updates the Remote World Spot List of each of these Remote Servers
0632:    //does not delete unreachable servers
0633:    //it is up to the user to manually do so by calling first updateRemoteServersList
0634:    public final void updateRemoteServers() {
0635:        
0636:        RemoteWorldSpotsAccess remoteWorldSpotsAccess;
0637:        Iterator iterator;
0638:        
0639:        iterator = this .getRemoteServers().iterator();
0640:        while (iterator.hasNext()) {
0641:            //query distant server and fetch informations
0642:            //distant server should send information to update
0643:            remoteWorldSpotsAccess = (RemoteWorldSpotsAccess)iterator.next();
0644:            remoteWorldSpotsAccess.updateRemoteWorldSpots(this );
0645:        }
0646:        
0647:    }
0648:    
0649:    //queries servers and delete unreachable servers
0650:    //be cautious before using this method as servers may be only temporary unreachable
0651:    public final void updateRemoteServersList() {
0652:        
0653:        Socket socket;
0654:        ObjectOutputStream objectOutputStream;
0655:        ObjectInputStream objectInputStream;
0656:        
0657:        ControlRequest controlRequest;
0658:        ControlReply controlReply;
0659:        RemoteWorldSpotsAccess remoteWorldSpotsAccess;
0660:        Iterator iterator;
0661:        
0662:        iterator = this .getRemoteServers().iterator();
0663:        while (iterator.hasNext()) {
0664:            //query distant server and fetch informations
0665:            //distant server should send information to update
0666:            remoteWorldSpotsAccess = (RemoteWorldSpotsAccess)iterator.next();
0667:            
0668:            try {
0669:                
0670:                //query distant server and fetch informations
0671:                socket = new Socket(this .getIP(), this .getPort(), remoteWorldSpotsAccess.getIP(), remoteWorldSpotsAccess.getPort());
0672:                
0673:                objectInputStream = new ObjectInputStream(socket.getInputStream());
0674:                objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
0675:                
0676:                controlRequest = new ControlRequest(ControlRequest.INFORMATION);
0677:                // send request
0678:                objectOutputStream.writeObject(controlRequest);
0679:                
0680:                // read response
0681:                try {
0682:                    
0683:                    controlReply = (ControlReply) objectInputStream.readObject();
0684:                    
0685:                    if (controlReply.getReplyKind()!=ControlReply.REFUSED) {
0686:                        
0687:                        this .removeRemoteServer(remoteWorldSpotsAccess);
0688:                    }
0689:                    
0690:                }
0691:                catch (ClassNotFoundException classNotFoundException) {
0692:                }
0693:                
0694:                objectOutputStream.flush();
0695:                objectInputStream.close();
0696:                objectOutputStream.close();
0697:                
0698:                socket.close();
0699:                
0700:            }
0701:            catch (IOException iOException) {
0702:            }
0703:            
0704:        }
0705:        
0706:    }
0707:    
0708:    public final HashSet getGates() {
0709:        
0710:        return this .gates;
0711:        
0712:    }
0713:    
0714:    //asynchronous addition while server running via a GUI side track tool
0715:    public final void setGates(HashSet gates) {
0716:        
0717:        this .gates = gates;
0718:        
0719:    }
0720:    
0721:    //asynchronous addition while server running via a GUI side track tool
0722:    public final void addGate(Gate gate) {
0723:        
0724:        this .gates.add(gate);
0725:        
0726:    }
0727:    
0728:    //asynchronous deletion while server running via a GUI side track tool
0729:    public final void removeGate(Gate gate) {
0730:        
0731:        this .gates.remove(gate);
0732:        
0733:    }
0734:    
0735:    //Queries the Gates to be sure they still serve some Virtual Worlds
0736:    //queries servers and delete unreachable servers
0737:    //be cautious before using this method as servers may be only temporary unreachable
0738:    public final void updateGates() {
0739:        
0740:        Socket socket;
0741:        ObjectOutputStream objectOutputStream;
0742:        ObjectInputStream objectInputStream;
0743:        
0744:        ControlRequest controlRequest;
0745:        ControlReply controlReply;
0746:        Gate gate;
0747:        Iterator iterator;
0748:        
0749:        iterator = this .getGates().iterator();
0750:        while (iterator.hasNext()) {
0751:            //query distant server and fetch informations
0752:            //distant server should send information to update
0753:            gate = (Gate)iterator.next();
0754:            
0755:            try {
0756:                
0757:                //query distant server and fetch informations
0758:                socket = new Socket(this .getIP(), this .getPort(), gate.getIP(), gate.getPort());
0759:                
0760:                objectInputStream = new ObjectInputStream(socket.getInputStream());
0761:                objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
0762:                
0763:                controlRequest = new ControlRequest(ControlRequest.INFORMATION);
0764:                // send request
0765:                objectOutputStream.writeObject(controlRequest);
0766:                
0767:                // read response
0768:                try {
0769:                    
0770:                    controlReply = (ControlReply) objectInputStream.readObject();
0771:                    
0772:                    if (controlReply.getReplyKind()!=ControlReply.REFUSED) {
0773:                        
0774:                        this .removeGate(gate);
0775:                    }
0776:                    
0777:                }
0778:                catch (ClassNotFoundException classNotFoundException) {
0779:                }
0780:                
0781:                objectOutputStream.flush();
0782:                objectInputStream.close();
0783:                objectOutputStream.close();
0784:                
0785:                socket.close();
0786:                
0787:            }
0788:            catch (IOException iOexception) {
0789:            }
0790:            
0791:        }
0792:        
0793:    }
0794:    
0795:    //send control request
0796:    private void sendControlRequest(Gate gate, ControlRequest controlRequest) {
0797:        
0798:        Socket socket;
0799:        ObjectOutputStream objectOutputStream;
0800:        
0801:        try {
0802:            
0803:            socket = new Socket(this .getIP(), this .getPort(), gate.getIP(), gate.getPort());
0804:            
0805:            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
0806:            
0807:            // send request
0808:            objectOutputStream.writeObject(controlRequest);
0809:            
0810:            objectOutputStream.flush();
0811:            objectOutputStream.close();
0812:            
0813:            socket.close();
0814:            
0815:        }
0816:        catch (IOException iOexception) {
0817:        }
0818:        
0819:    }
0820:    
0821:    private void waitControlRequest(Gate gate, ControlRequest controlRequest) {
0822:        
0823:        Socket socket;
0824:        ObjectInputStream objectInputStream;
0825:        ControlReply controlReply;
0826:        
0827:        try {
0828:            
0829:            //query distant server and fetch informations
0830:            socket = new Socket(this .getIP(), this .getPort(), gate.getIP(), gate.getPort());
0831:            
0832:            objectInputStream = new ObjectInputStream(socket.getInputStream());
0833:            
0834:            // read response
0835:            try {
0836:                controlReply = (ControlReply) objectInputStream.readObject();
0837:            }
0838:            catch (ClassNotFoundException classNotFoundException) {
0839:            }
0840:            
0841:            objectInputStream.close();
0842:            
0843:            socket.close();
0844:            
0845:        }
0846:        catch (IOException iOexception) {
0847:        }
0848:        
0849:    }
0850:    
0851:    //work control request
0852:    private ControlReply workOutControlRequest(ControlRequest controlRequest) {
0853:        
0854:        ControlReply controlReply;
0855:        
0856:        controlReply = new ControlReply(ControlReply.ACCEPTED);
0857:        
0858:        if (controlRequest.getAccessKind()==ControlRequest.INFORMATION) {
0859:            controlReply.setObjectValue(this .getInformation());
0860:        } else {
0861:            if (controlRequest.getAccessKind()==ControlRequest.LOCALWORLDSPOTS) {
0862:                controlReply.setObjectValue(this .getLocalWorldSpots());
0863:            } else {
0864:                if (controlRequest.getAccessKind()==ControlRequest.REMOTEWORLDSPOTS) {
0865:                    controlReply.setObjectValue(this .getRemoteServers());
0866:                } else {
0867:                    if (controlRequest.getAccessKind()==ControlRequest.GATES) {
0868:                        controlReply.setObjectValue(this .getGates());
0869:                    } else {
0870:                        //(controlRequest.getAccessKind()==ControlRequest.TIME)
0871:                        controlReply.setObjectValue(new Long(this .getServerTime()));
0872:                    }
0873:                }
0874:            }
0875:        }
0876:        
0877:        return controlReply;
0878:        
0879:    }
0880:    
0881:    //socket should be an active socket from which the notification was received
0882:    private void workOutControlNotification(Socket socket, ControlNotification controlNotification) {
0883:        
0884:        Gate gate;
0885:        ControlRequest controlRequest;
0886:        
0887:        //use socket parameters
0888:        gate = new Gate(socket.getInetAddress(), socket.getPort());
0889:        
0890:        if (controlNotification.getNotifyKind()==ControlNotification.LOCALWORLDSPOTS) {
0891:            //retrieve IP of server to send a ControlRequest
0892:            controlRequest = new ControlRequest(ControlRequest.LOCALWORLDSPOTS);
0893:            this .sendControlRequest(gate, controlRequest);
0894:        } else {
0895:            //(controlNotification.getNotifyKind()==ControlNotification.ENDOFSERVICE)
0896:            this .removeGate(gate);
0897:        }
0898:        
0899:    }
0900:    
0901:    //send control reply
0902:    private void sendControlReply(Gate gate, ControlReply controlReply) {
0903:        
0904:        Socket socket;
0905:        ObjectOutputStream objectOutputStream;
0906:        
0907:        try {
0908:            
0909:            socket = new Socket(this .getIP(), this .getPort(), gate.getIP(), gate.getPort());
0910:            
0911:            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
0912:            
0913:            // send request
0914:            objectOutputStream.writeObject(controlReply);
0915:            
0916:            objectOutputStream.flush();
0917:            objectOutputStream.close();
0918:            
0919:            socket.close();
0920:            
0921:        }
0922:        catch (IOException iOexception) {
0923:        }
0924:        
0925:    }
0926:    
0927:    //read control reply
0928:    private void workOutControlReply(ControlReply controlReply) {
0929:        
0930:        //YYYYYYYYYYYYYYYYYYY
0931:    }
0932:    
0933:    //called automatically when reaching world spot boundary or from user request originating from WorldSpot
0934:    
0935:    //this actually sends the object or kicks out the Avatar (the Status of the Original avatar is set to Avatar.AWAY)
0936:    //from one World Spot to another (may be not on the same Server)
0937:    //position is the desired final position
0938:    //Object (which must be ObjectWorld, BackgroundWorld or Avatar) may not arrive where you want (due to ruler's objection or may even fail)
0939:    //if position is in the current World Spot, Object is just move according standard user rights
0940:    //clientInformation is changed on the client side to smoothly operate transition in case you exported your avatar (emigration)
0941:    public final void export(VirtualElement virtualElement, Transform3D position) {
0942:        
0943:        boolean found;
0944:        WorldSpot worldSpot;
0945:        RemoteWorldSpotsAccess remoteWorldSpotsAccess;
0946:        Iterator iterator;
0947:        Iterator iterator2;
0948:        Avatar avatar;
0949:        Vector3d vectorTransform;
0950:        Bounds backGroundWorldBounds;
0951:        
0952:        if ((virtualElement!=null) && (position!=null)) {
0953:            
0954:            worldSpot = virtualElement.getWorldSpot(virtualElement.getUserOwner());
0955:            //get object current worldSpot
0956:            //verify position is outside of worldspot
0957:            vectorTransform = new Vector3d();
0958:            position.get(vectorTransform);
0959:            if (!worldSpot.getBounds().intersect(new Point3d(vectorTransform))) {
0960:                //verify there exist a worldspot with the receiving position
0961:                iterator = this .getLocalWorldSpots().iterator();
0962:                found = false;
0963:                while (iterator.hasNext() && (!found)) {
0964:                    worldSpot = (WorldSpot)iterator.next();
0965:                    found = worldSpot.getBounds().intersect(new Point3d(vectorTransform));
0966:                }
0967:                if (found) {
0968:                    //if the worldspot is on the same server
0969:                    if (virtualElement instanceof  ObjectWorld) {
0970:                        ((ObjectWorld)virtualElement).setTransform3D(position);
0971:                    }
0972:                    //YYYYYYYYYYYYYYYYYY
0973:                } else {
0974:                    found = false;
0975:                    iterator = this .getRemoteServers().iterator();
0976:                    while (iterator.hasNext() && (!found)) {
0977:                        remoteWorldSpotsAccess = (RemoteWorldSpotsAccess) iterator.next();
0978:                        iterator2 = remoteWorldSpotsAccess.getRemoteWorldSpots(this ).iterator();
0979:                        while (iterator.hasNext() && (!found)) {
0980:                            worldSpot = (WorldSpot)iterator.next();
0981:                            found = worldSpot.getBounds().intersect(new Point3d(vectorTransform));
0982:                        }
0983:                    }
0984:                    if (found) {
0985:                        //if the worldspot is on a different server
0986:                        //contact the server and ask if it can instanciate an object with the same features and delete this virtualElement
0987:                        //create an avatar that mimics current avatar to provide an owner and a receiver for the account if tourism occurs
0988:                        //YYYYYYYYYYYYYYYYY
0989:                        if (!worldSpot.getRuler().checkLoginAndPasswordExists(virtualElement.getUserOwner().getLoginInformation())) {
0990:                            //else the account already exists
0991:                            //YYYYYYYYYYYYYYYYY
0992:                            avatar = Avatar.createUserAccount(virtualElement.getUserOwner().getLoginInformation(), worldSpot.getRuler());
0993:                            //YYYY home position may be not on the same worldSpot
0994:                            worldSpot.instanciateSkinFromLibrary(virtualElement.getUserOwner().getSkin().getClass(), avatar, avatar.getHomePosition());
0995:                        } else {
0996:                            avatar = worldSpot.getRuler().findAvatar(virtualElement.getUserOwner().getLoginInformation());
0997:                        }
0998:                        if (virtualElement instanceof  ObjectWorld) {
0999:                            if (virtualElement instanceof  Skin) {
1000:                                worldSpot.instanciateSkinFromLibrary(((Skin)virtualElement).getClass(), avatar, position);
1001:                            }  else {
1002:                                worldSpot.instanciateObjectWorldFromLibrary(((ObjectWorld)virtualElement).getClass(), avatar, position);
1003:                            }
1004:                        } else {
1005:                            if (virtualElement instanceof  BackgroundWorld) {
1006:                                backGroundWorldBounds = ((BackgroundWorld)virtualElement).getBounds();
1007:                                backGroundWorldBounds.transform(position);
1008:                                worldSpot.instanciateBackgroundWorldFromLibrary(((BackgroundWorld)virtualElement).getClass(), avatar, backGroundWorldBounds);
1009:                            }
1010:                        }
1011:                        virtualElement.deleteVirtualElement(virtualElement.getUserOwner(), virtualElement);
1012:                    } else {
1013:                        //don't export because position is invalid
1014:                    }
1015:                }
1016:            }
1017:            
1018:        }
1019:        
1020:    }
1021:    
1022:    //same as export but between virtual worlds
1023:    //position is the desired final position (it may not exist and the Object should be transfered in the World Spot near Transform3D.ZERO)
1024:    public final void export(VirtualElement virtualElement, Gate gate, Transform3D position) {
1025:        
1026:        Avatar avatar;
1027:        WorldSpot worldSpot;
1028:        Bounds backGroundWorldBounds;
1029:        
1030:        if ((virtualElement!=null) && (position!=null) && (gate!=null)) {
1031:            
1032:            //object may be lost in the transfert
1033:            //contact the server and ask if it can instanciate an object with the same features and delete this virtualElement
1034:            //YYYYYYYY  XXXXXXXXX
1035:            //worldSpot = ;
1036:            //create an avatar that mimics current avatar to provide an owner and a receiver for the account if tourism occurs
1037:            //YYYYYYYYYYYYYYYYY
1038:            if (!worldSpot.getRuler().checkLoginAndPasswordExists((virtualElement.getUserOwner().getLoginInformation()))) {
1039:                //else the account already exists
1040:                //YYYYYYYYYYYYYYYYY
1041:                avatar = Avatar.createUserAccount(virtualElement.getUserOwner().getLoginInformation(), worldSpot.getRuler());
1042:                worldSpot.instanciateSkinFromLibrary(virtualElement.getUserOwner().getSkin().getClass(), avatar, avatar.getHomePosition());
1043:            }
1044:            else {
1045:                avatar = worldSpot.getRuler().findAvatar(virtualElement.getUserOwner().getLoginInformation());
1046:            }
1047:            if (virtualElement instanceof  ObjectWorld) {
1048:                if (virtualElement instanceof  Skin) {
1049:                    worldSpot.instanciateSkinFromLibrary(((Skin)virtualElement).getClass(), avatar, position);
1050:                }  else {
1051:                    worldSpot.instanciateObjectWorldFromLibrary(((ObjectWorld)virtualElement).getClass(), avatar, position);
1052:                }
1053:            } else {
1054:                if (virtualElement instanceof  BackgroundWorld) {
1055:                    backGroundWorldBounds = ((BackgroundWorld)virtualElement).getBounds();
1056:                    backGroundWorldBounds.transform(position);
1057:                    worldSpot.instanciateBackgroundWorldFromLibrary(((ObjectWorld)virtualElement).getClass(), avatar, backGroundWorldBounds);
1058:                }
1059:            }
1060:            //YYYYYYYYYYYYYYYYY
1061:            virtualElement.deleteVirtualElement(virtualElement);
1062:        }
1063:    }
1064:    
1065:    //good to use when a World Spot is about to be closed
1066:    //transfer users to another World Spot with pawns and belongings
1067:    //Objects are transfered to new Lands if they can as usual
1068:    //in fact everything happens just like if translated from original worldSpot location (relative to its center) to position
1069:    //thus transferContents(sourceWorldSpot, new BoundingSphere(sourceWorldSpot.getBounds()).getCenter()) is a null operation
1070:    //multiple worldSpots may own the resulting objects
1071:    //tip: make a phone call to the destination ruler and warn him that something is going to happen
1072:    //transfer between servers
1073:    //basically copies the current world spot to a remote server and deletes it from the local server
1074:    //theorically it should be smooth and safe for users but because it is not really possible to make a snapshot
1075:    //of a world and changing every client connection rapidly there should be some delays at least
1076:    //this command will probably generate a mess on the destination world
1077:    //much of what was in the original world including relative position of objects may be lost in the transfer
1078:    public final void transferContents(WorldSpot sourceWorldSpot, Transform3D position) {
1079:        
1080:        Transaction transaction;
1081:        Extent extent;
1082:        Query query;
1083:        String filter;
1084:        Collection collection;
1085:        Iterator iterator;
1086:        VirtualElement virtualElement;
1087:        Transform3D offset;
1088:        Point3d point3d;
1089:        Transform3D transformPoint3d;
1090:        
1091:        if ((sourceWorldSpot!=null) && (position!=null)) {
1092:            
1093:            try {
1094:                transaction = this .getPersistenceManager().currentTransaction();
1095:                transaction.begin();
1096:                
1097:                extent = this .getPersistenceManager().getExtent(VirtualElement.class, true);
1098:                filter = new String("SELECT * FROM VirtualElement");
1099:                query = this .getPersistenceManager().newQuery(VirtualElement.class, extent, filter);
1100:                collection = (Collection) query.execute();
1101:                
1102:                transaction.commit();
1103:            }
1104:            catch (Exception exception) {
1105:            }
1106:            
1107:            point3d = new BoundingSphere(sourceWorldSpot.getBounds()).getCenter();
1108:            transformPoint3d = new Transform3D();
1109:            offset = new Transform3D(position);
1110:            transformPoint3d.set(new Vector3d(point3d.x, point3d.y, point3d.z));
1111:            offset.sub(transformPoint3d);
1112:            
1113:            iterator = collection.iterator();
1114:            
1115:            while (iterator.hasNext()) {
1116:                virtualElement = (VirtualElement) iterator.next();
1117:                if (virtualElement instanceof  ObjectWorld) {
1118:                this .export(virtualElement, ((ObjectWorld)virtualElement).getTransform3D().add(offset));
1119:            } else {
1120:                this .export(virtualElement, position);
1121:            }
1122:            }
1123:            
1124:        }
1125:        
1126:       
1127:        //YYYYYYYY XXXXX
1128:        //check bounds are big enough to receive the worldSpot
1129:        //create accounts
1130:        //rebuild filters, blockers, pass, tickets, home position, capabilities and policies
1131:        //reconnect to pools
1132:        //build remaing lands
1133:        //populate libraries
1134:        //instanciate objects
1135:        //reconnect every client to new worldSpot
1136:        //delete old worldspot
1137:        
1138:    }
1139:    
1140:    //same as transfer but between virtual worlds
1141:    //position "describes" the world spot of destination
1142:    //this command will probably generate a mess on the destination world
1143:    //much of what was in the original world including relative position of objects may be lost in the transfer
1144:    public final void transferContents(WorldSpot worldSpot, Gate gate, Transform3D position) {
1145:        
1146:        Transaction transaction;
1147:        Extent extent;
1148:        Query query;
1149:        String filter;
1150:        Collection collection;
1151:        Iterator iterator;
1152:        VirtualElement virtualElement;
1153:        Transform3D offset;
1154:        Transform3D result;
1155:        Point3d point3d;
1156:        
1157:        if ((worldSpot!=null) && (gate!=null) && (position!=null)) {
1158:            
1159:            try {
1160:                transaction = this .getPersistenceManager().currentTransaction();
1161:                transaction.begin();
1162:                
1163:                extent = this .getPersistenceManager().getExtent(VirtualElement.class, true);
1164:                filter = new String("SELECT * FROM VirtualElement");
1165:                query = this .getPersistenceManager().newQuery(VirtualElement.class, extent, filter);
1166:                collection = (Collection) query.execute();
1167:                
1168:                transaction.commit();
1169:                
1170:                point3d = new Point3d();
1171:                new BoundingSphere(worldSpot.getBounds()).getCenter(point3d);
1172:                offset = new Transform3D();
1173:                offset.set(new Vector3d(point3d.x, point3d.y, point3d.z));
1174:                result = new Transform3D(position);
1175:                result.sub(offset);
1176:                
1177:                iterator = collection.iterator();
1178:                
1179:                while (iterator.hasNext()) {
1180:                    virtualElement = (VirtualElement) iterator.next();
1181:                    if (virtualElement instanceof  ObjectWorld) {
1182:                        offset = new Transform3D(((ObjectWorld)virtualElement).getTransform3D());
1183:                        offset.add(result);
1184:                        this .export(virtualElement, gate, offset);
1185:                    } else {
1186:                        this .export(virtualElement, gate, position);
1187:                    }
1188:                }
1189:                
1190:            }
1191:            catch (Exception exception) {
1192:            }
1193:            
1194:        }
1195:        
1196:        //YYYYYYYY  XXXXX
1197:        
1198:    }
1199:    
1200:    //closes all active connections in the given LOCAL world spot
1201:    //avatars are therefore all Avatar.AWAY
1202:    public final void evict(WorldSpot worldSpot) {
1203:        
1204:        Collection avatars;
1205:        Iterator iterator;
1206:        Avatar avatar;
1207:        
1208:        if ((worldSpot!=null) && (this .getLocalWorldSpots().contains(worldSpot))) {
1209:            
1210:            avatars = worldSpot.getAvatars(worldSpot.getRuler());
1211:            
1212:            iterator = avatars.iterator();
1213:            while (iterator.hasNext()) {
1214:                avatar = (Avatar) iterator.next();
1215:                this .closeConnection(avatar);
1216:            }
1217:            
1218:        }
1219:        
1220:    }
1221:    
1222:    //when this Server is going to be closed, send a message to all remaining users
1223:    //and to all gates
1224:    //date is the date after which the server is meant to be unreliable
1225:    //asynchronous call while server running via a GUI side track tool
1226:    public final void warnEndOfService(Date date) {
1227:        
1228:        Socket socket;
1229:        ObjectOutputStream objectOutputStream;
1230:        
1231:        ControlNotification controlNotification;
1232:        WorldSpot worldSpot;
1233:        WorldSpotBasicInformation worldSpotBasicInformation;
1234:        RemoteWorldSpotsAccess remoteWorldSpotsAccess;
1235:        Gate gate;
1236:        Iterator iterator;
1237:        
1238:        //send message to remaining users on local world spots
1239:        iterator = this .getLocalWorldSpots().iterator();
1240:        while (iterator.hasNext()) {
1241:            worldSpot= (WorldSpot) iterator.next();
1242:            worldSpotBasicInformation = new WorldSpotBasicInformation(worldSpot.getRuler(), worldSpot.getBounds(), worldSpot.getInformation());
1243:        }
1244:        
1245:        //send message to remaining users of remote servers (distant world spots)
1246:        iterator = this .getRemoteServers().iterator();
1247:        while (iterator.hasNext()) {
1248:            remoteWorldSpotsAccess = (RemoteWorldSpotsAccess)iterator.next();
1249:            
1250:            try {
1251:                
1252:                //query distant server and send information
1253:                socket = new Socket(this .getIP(), this .getPort(), remoteWorldSpotsAccess.getIP(), remoteWorldSpotsAccess.getPort());
1254:                
1255:                objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
1256:                
1257:                controlNotification = new ControlNotification(ControlNotification.ENDOFSERVICE, date);
1258:                // send request
1259:                objectOutputStream.writeObject(controlNotification);
1260:                
1261:                // read response
1262:                objectOutputStream.flush();
1263:                objectOutputStream.close();
1264:                
1265:                socket.close();
1266:                
1267:            }
1268:            catch (IOException iOexception) {
1269:            }
1270:        }
1271:        
1272:        //send message to gates
1273:        iterator = this .getGates().iterator();
1274:        while (iterator.hasNext()) {
1275:            gate = (Gate)iterator.next();
1276:            
1277:            try {
1278:                //query distant server and send information
1279:                socket = new Socket(this .getIP(), this .getPort(), gate.getIP(), gate.getPort());
1280:                objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
1281:                
1282:                controlNotification = new ControlNotification(ControlNotification.ENDOFSERVICE, date);
1283:                // send request
1284:                objectOutputStream.writeObject(controlNotification);
1285:                
1286:                // read response
1287:                objectOutputStream.flush();
1288:                objectOutputStream.close();
1289:                
1290:                socket.close();
1291:                
1292:            } catch (IOException iOException) {
1293:            }
1294:            
1295:        }
1296:        
1297:    }
1298:    
1299:    //does a warn and closes everything smoothly
1300:    public final void doEndOfService() {
1301:        
1302:        HashSet worldSpots;
1303:        Iterator iterator;
1304:        WorldSpot worldSpot;
1305:        
1306:        this .warnEndOfService(new Date(System.currentTimeMillis()));
1307:        worldSpots = this .getLocalWorldSpots();
1308:        iterator = worldSpots.iterator();
1309:        while(iterator.hasNext()) {
1310:            worldSpot = (WorldSpot) iterator.next();
1311:            this .evict(worldSpot);
1312:        }
1313:        
1314:    }
1315:    
1316:    //asynchronous call while server running via a GUI side track tool
1317:    //automatically manages Gates by using a ServerHelper
1318:    //calls to addGates and setGates are made
1319:    //useful to add gates to ease travel use of your users between virtual worlds
1320:    public void queryServerHelper(InetAddress IP, int port) {
1321:        
1322:        ServerHelper serverHelper;
1323:        HashSet hashSet;
1324:        Gate gate;
1325:        
1326:        serverHelper = new ServerHelper(this .getIP(), this .getPort());
1327:        gate = new Gate(IP, port);
1328:        hashSet = serverHelper.getGates(gate);
1329:        hashSet.addAll(this .getGates());
1330:        this .setGates(hashSet);
1331:        
1332:    }
1333:    
1334:    //asynchronous call while server running via a GUI side track tool
1335:    //automatically manages Gates by using a ServerHelper
1336:    //calls to addGates and setGates are made
1337:    //useful to add gates to ease travel use of your users between virtual worlds
1338:    //uses a wellKnownServer
1339:    public void queryServerHelper() {
1340:        
1341:        ServerHelper serverHelper;
1342:        HashSet hashSet;
1343:        
1344:        serverHelper = new ServerHelper(this .getIP(), this .getPort());
1345:        hashSet = serverHelper.getGates(serverHelper.getWellKnownServer());
1346:        hashSet.addAll(this .getGates());
1347:        this .setGates(hashSet);
1348:        
1349:    }
1350:    
1351:    public long getServerTime() {
1352:        
1353:        return System.currentTimeMillis() + offset;
1354:        
1355:    }
1356:    
1357:    //asynchronous addition while server running via a GUI side track tool
1358:    public void setServerTimeOffset(long offset) {
1359:        
1360:        this .offset = offset;
1361:        
1362:    }
1363:    
1364:    //starts the server threads
1365:    public void start() {
1366:        
1367:    }
1368:    
1369:    //stops the server
1370:    public void stop() {
1371:        
1372:        try {
1373:            this .getPersistenceManager().close();
1374:            // this is done so that database can shut down properly
1375:            //YYYYYYYYYYYYYYYYYY
1376:            //fOStorePMF.close();
1377:        }
1378:        catch (Exception exception) {
1379:        }
1380:        
1381:        //close network
1382:        try {
1383:            
1384:            serverSocket.close();
1385:            
1386:        } catch (IOException iOException) {
1387:        }
1388:        
1389:    }
1390:    
1391:    //sort of duplicate method with Avatar but the Avatar method can only be called when there is at least an avatar
1392:    //behavior and parameters should roughly be the same
1393:    public Avatar createRuler(LoginInformation loginInformation) {
1394:        
1395:        Avatar ruler;
1396:        Transaction transaction;
1397:        
1398:        ruler = new Avatar(this , loginInformation);
1399:        
1400:        //ruler is allocated full worldSpot Land at worldSpot instanciation
1401:        try {
1402:            
1403:            transaction = this .getPersistenceManager().currentTransaction();
1404:            transaction.begin();
1405:            
1406:            this .getPersistenceManager().makePersistent(ruler);
1407:            
1408:            transaction.commit();
1409:        }
1410:        catch (Exception exception) {
1411:        }
1412:        
1413:        return ruler;
1414:        
1415:    }
1416:    
1417:    
1418:    //be sure to add a new thread when adding a new world spot
1419:    //the thread should implement the double cache system database-clients
1420:    //and ensure proper slicing of tools and guides behaviors
1421:    
1422:    //The "listen" thread that accepts a connection to the server.
1423:    //running thread to receive and treat Client requests
1424:    
1425:    public void run() {
1426:        
1427:        Socket socket;
1428:        
1429:        Authentification authentification;
1430:        ClientInformation clientInformation;
1431:        Avatar avatar;
1432:        int accessKind;
1433:        ObjectOutputStream objectOutputStream;
1434:        ObjectInputStream objectInputStream;
1435:        InputStream inputStream;
1436:        OutputStream outputStream;
1437:        //GZIPOutputStream gZIPOutputStream;
1438:        //GZIPInputStream gZIPInputStream;
1439:        BufferedOutputStream bufferedOutputStream;
1440:        BufferedInputStream bufferedInputStream;
1441:        
1442:        // accept a connection
1443:        try {
1444:            socket = serverSocket.accept();
1445:            socket.setTcpNoDelay(true);
1446:        } catch (IOException iOException) {
1447:            System.out.println("Server died: " + iOException.getMessage());
1448:            iOException.printStackTrace();
1449:            return;
1450:        }
1451:        
1452:        // create a new thread to accept the next connection
1453:        this .newListener();
1454:        //the other solution would be to start the client in a new thread and keep looping on this thread
1455:        
1456:        try {
1457:            //gZIPOutputStream = GZIPOutputStream(socket.getOutputStream());
1458:            //bufferedOutputStream = new BufferedOutputStream(gZIPOutputStream);
1459:            bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
1460:            objectOutputStream = new ObjectOutputStream(bufferedOutputStream);
1461:            
1462:            //gZIPInputStream = GZIPInputStream(socket.getInputStream());
1463:            //bufferedInputStream = new BufferedInputStream(gZIPInputStream);
1464:            bufferedInputStream = new BufferedInputStream(socket.getInputStream());
1465:            objectInputStream = new ObjectInputStream(bufferedInputStream);
1466:            
1467:            authentification = (Authentification) objectInputStream.readObject();
1468:            
1469:            clientInformation = new ClientInformation(authentification.getIP(), authentification.getPort(), new String(""), this .getIP(), this .getPort(), authentification.getLoginInformation(), new Transform3D());
1470:            accessKind = authentification.getAccessKind();
1471:            
1472:            switch (accessKind) {
1473:                //addition and connect for the first time immediately are an immigration
1474:                //you can use this process either for full accounts or guest accounts
1475:                case Authentification.IMMIGRATE: {
1476:                    this .addAccount(clientInformation);
1477:                    this .reconnect(clientInformation);
1478:                }
1479:                //only adds account but does not open a client connection, useful mainly for ruler to set up batch accounts
1480:                case Authentification.ADDITION: {
1481:                    this .addAccount(clientInformation);
1482:                }
1483:                case Authentification.RECONNECT: {
1484:                    //reconnect is the normal way of login to your account
1485:                    this .reconnect(clientInformation);
1486:                }
1487:                case Authentification.CLOSE_SESSION: {
1488:                    //to manually close the connection
1489:                    //server should close connection by itself if client is lost (power failure, network failure...)
1490:                    avatar = this .getAvatar(clientInformation);
1491:                    if (avatar!=null) {
1492:                        avatar.disconnectUser();
1493:                    }
1494:                    this .closeConnection(clientInformation);
1495:                }
1496:                case Authentification.DELETION: {
1497:                    //Deletes account
1498:                    //Does note need to be logged on to delete the account
1499:                    //actually closes the the connection if connected
1500:                    avatar = this .getAvatar(clientInformation);
1501:                    if (avatar!=null) {
1502:                        avatar.setStatus(Avatar.PAWN);
1503:                    }
1504:                    this .closeConnection(clientInformation);
1505:                }
1506:                case Authentification.IMMEDIATE_DELETION: {
1507:                    //Deletes also all properties using Avatar.TRASH_ALL as succession policy
1508:                    //not very cool for those who stay
1509:                    avatar = this .getAvatar(clientInformation);
1510:                    if (avatar!=null) {
1511:                        avatar.setSuccessionPolicy(Avatar.TRASH_ALL,Avatar.TRASH_ALL,Avatar.TRASH_ALL);
1512:                        avatar.setStatus(Avatar.PAWN);
1513:                    }
1514:                    this .closeConnection(clientInformation);
1515:                }
1516:            }
1517:            
1518:            //YYYYYYYYYYYYYYYYYYYYYYYYyy
1519:            //this.sleep(300);
1520:            
1521:        }
1522:        catch (Exception exception) {
1523:        }
1524:        
1525:    }
1526:    
1527:    /**
1528:     * Create a new thread to listen.
1529:     */
1530:    private void newListener() {
1531:        
1532:        (new Thread(this )).start();
1533:        
1534:    }
1535:    
1536:    //may return null
1537:    private Avatar getAvatar(ClientInformation clientInformation) {
1538:        
1539:        Transaction transaction;
1540:        Extent extent;
1541:        Query query;
1542:        String filter;
1543:        Collection collection;
1544:        
1545:        if (clientInformation!=null) {
1546:            try {
1547:                transaction = this .getPersistenceManager().currentTransaction();
1548:                transaction.begin();
1549:                
1550:                extent = this .getPersistenceManager().getExtent(Avatar.class, true);
1551:                filter = new String("SELECT Avatar FROM Avatar a WHERE a.getLoginInformation().checkLoginAndPassword(clientInformation.getLoginInformation())==true");
1552:                query = this .getPersistenceManager().newQuery(Avatar.class, extent, filter);
1553:                collection = (Collection) query.execute();
1554:                
1555:                transaction.commit();
1556:                
1557:                if (collection.size()!=0) {
1558:                    return (Avatar)(collection.iterator().next());
1559:                }
1560:                else {
1561:                    return null;
1562:                }
1563:                
1564:            }
1565:            catch (Exception exception) {
1566:                return null;
1567:            }
1568:            
1569:        }
1570:        else {
1571:            return null;
1572:        }
1573:        
1574:    }
1575:    
1576:    // check if there is no active client for that account
1577:    //don't open connection if so
1578:    //reply cause of failure to user
1579:    //YYYYYYYY  XXXXXXX
1580:    private void addAccount(ClientInformation clientInformation) {
1581:        
1582:        Avatar.createUserAccount(clientInformation.getLoginInformation());
1583:        avatar.setStatus(Avatar.AWAY);
1584:        
1585:    }
1586:    
1587:    //return reply account not found or start as guest
1588:    //YYYYYYYY  XXXX
1589:    private void reconnect(ClientInformation clientInformation) {
1590:        
1591:        if (status()!=Avatar.Pawn) {
1592:            //YYYYYYYY XXXXX
1593:            //check position is on this server and find worldspot else send a message to client containing the correct ip and port to access the server
1594:            avatar.setStatus(Avatar.IMMIGRATE);
1595:            avatar.setStatus(Avatar.NORMAL);
1596:            //YYYYYYYY  XXXX
1597:        }
1598:
1599:    }
1600:    
1601:    //YYYYYYYY XXXX
1602:    public void closeConnection(Avatar avatar) {
1603:    }
1604:    
1605:    //YYYYYYYY XXXX
1606:    public void closeConnection(ClientInformation clientInformation) {
1607:        
1608:         try {
1609:            objectOutputStream.flush();
1610:            objectOutputStream.close();
1611:            //gZIPOutputStream.flush();
1612:            //gZIPOutputStream.finish();
1613:            //gZIPOutputStream.close();
1614:            bufferedOutputStream.flush();
1615:            bufferedOutputStream.close();
1616:            
1617:            objectInputStream.close();
1618:            //gZIPInputStream.close();
1619:            bufferedInputStream.close();
1620:            
1621:            socket.close();
1622:        } catch (IOException e) {
1623:        }
1624:        
1625:   }
1626:    
1627:    //if no response from this client for some time close this serversocket and this thread
1628:    private void autoCloseConnection(ClientInformation clientInformation) {
1629:        
1630:        this .closeConnection(clientInformation);
1631:        
1632:    }
1633:    
1634:    //server out cache
1635:    private HashSet sendObjects;
1636:    
1637:    //when the client logs a special request is made to send everything and not just updated objects
1638:    //client exists or a new account is created as direct child to the ruler
1639:    //YYYYYYYY XXXX
1640:    private HashSet workOutFirstRequest(ClientInformation clientInformation) {
1641:        
1642:         LoginInformation loginInformation;
1643:        BoundingSphere boundingSphere;
1644:        Transaction transaction;
1645:        Extent extent;
1646:        Query query;
1647:        String filter;
1648:        Collection collection;
1649:        Avatar avatar;
1650:        Iterator iterator;
1651:        Point3d positionAsPoint;
1652:        Vector3d positionAsVector;
1653:        Collection simpleCollection;
1654:        NetworkElement networkElement;
1655:        HashSet resultCollection;
1656:        Collection collection1;
1657:        Collection collection2;
1658:        boolean found;
1659:        Iterator iterator2;
1660:        Collection blockerCollection;
1661:        
1662:        loginInformation = clientInformation.getLoginInformation();
1663:        
1664:        try {
1665:            transaction = this .getPersistentManager().currentTransaction();
1666:            transaction.begin();
1667:            
1668:            extent = this .getPersistentManager().getExtent(Avatar.class, true);
1669:            filter = new String("SELECT Avatar FROM Avatar a WHERE a.getLoginInformation().checkLoginAndPassword(loginInformation)==true");
1670:            query = this .getPersistentManager().newQuery(Avatar.class, extent, filter);
1671:            collection = (Collection) query.execute();
1672:            
1673:            transaction.commit();
1674:        }
1675:        catch (Exception exception) {
1676:        }
1677:        
1678:        if (collection.size()==0) {
1679:            //or start a new account
1680:            avatar = Avatar.createUserAccount(loginInformation, this .getWorldSpot().getRuler());
1681:            avatar.setStatus(Avatar.IMMIGRATING);
1682:            avatar.setStatus(Avatar.NORMAL);
1683:        } else {
1684:            avatar = (Avatar) collection.iterator.next();
1685:            avatar.setStatus(Avatar.NORMAL);
1686:        }
1687:        
1688:        //start connection
1689:        
1690:        //try to set the avatar to the desired position
1691:        if (avatar.getSkin()!=null) {
1692:            avatar.getSkin().setTransform3D(clientInformation.getPosition());
1693:            clientInformation.setPosition(avatar.getSkin().getTransform3D());
1694:        }
1695:        
1696:        //use the client scope
1697:        boundingSphere = new BoundingSphere(clientInformation.getPosition(), clientInformation.getDrawingRadius());
1698:        
1699:        //get land the avatar is on
1700:        try {
1701:            transaction = this .getPersistentManager().currentTransaction();
1702:            transaction.begin();
1703:            
1704:            extent = this .getPersistentManager().getExtent(Filter.class, true);
1705:            filter = new String("SELECT Land FROM Land l WHERE l.getBounds().intersects(boundingSphere)");
1706:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
1707:            collection = (Collection) query.execute();
1708:            
1709:            transaction.commit();
1710:        }
1711:        catch (Exception exception) {
1712:        }
1713:        
1714:        positionAsVector = new Vector3d();
1715:        clientInformation.getPosition().get(positionAsVector);
1716:        positionAsPoint = new Point3d(positionAsVector);
1717:        found = false;
1718:        iterator = collection.iterator();
1719:        while (iterator.hasNext() && (!found)) {
1720:            land = (Land)iterator.next();
1721:            found = land.getBounds().intersect(positionAsPoint);
1722:        }
1723:        
1724:        simpleCollection = new Collection(collection);
1725:        
1726:        //whether in his home or on someone's land, this land should be navigable for that user because of the previous setTransform
1727:        if (found) {
1728:            land.doEnter(avatar);
1729:            simpleCollection.remove(land);
1730:        }
1731:        
1732:        iterator = simpleCollection.iterator();
1733:        while (iterator.hasNext()) {
1734:            ((Land)iterator.next()).doLook(avatar);
1735:        }
1736:        
1737:        //get and display stuff depending on land capabilities
1738:        
1739:        //select matching BackgroundWorlds from bounds and capabilities
1740:        try {
1741:            transaction = this .getPersistentManager().currentTransaction();
1742:            transaction.begin();
1743:            
1744:            extent = this .getPersistentManager().getExtent(Filter.class, true);
1745:            filter = new String("SELECT BackgroundWorld FROM BackgroundWorld b WHERE b.getGeometryBounds().intersects(boundingSphere)");
1746:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
1747:            collection1 = (Collection) query.execute();
1748:            
1749:            transaction.commit();
1750:        }
1751:        catch (Exception exception) {
1752:        }
1753:        
1754:        //select matching ObjectWorlds from bounds and capabilities
1755:        try {
1756:            transaction = this .getPersistentManager().currentTransaction();
1757:            transaction.begin();
1758:            
1759:            extent = this .getPersistentManager().getExtent(Filter.class, true);
1760:            filter = new String("SELECT ObjectWorld FROM ObjectWorld o WHERE o.getGeometryBounds().intersects(boundingSphere)");
1761:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
1762:            collection2 = (Collection) query.execute();
1763:            
1764:            transaction.commit();
1765:        }
1766:        catch (Exception exception) {
1767:        }
1768:        
1769:        collection = this .filterCollection(avatar, collection1.addAll(collection2));
1770:        
1771:        //find blockers
1772:        try {
1773:            transaction = this .getPersistentManager().currentTransaction();
1774:            transaction.begin();
1775:            
1776:            extent = this .getPersistentManager().getExtent(Filter.class, true);
1777:            filter = new String("SELECT Blocker FROM Blocker b WHERE b.getRequester()==avatar");
1778:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
1779:            blockerCollection = (Collection) query.execute();
1780:            
1781:            transaction.commit();
1782:        }
1783:        catch (Exception exception) {
1784:        }
1785:        
1786:        //don't send blockers
1787:        
1788:        iterator = collection.iterator();
1789:        resultCollection = new HashSet();
1790:        while (iterator.hasNext()) {
1791:            virtualElement = (VirtualElement) iterator.next();
1792:            
1793:            virtualElement.doVisible();
1794:            virtualElement.doSonore();
1795:            
1796:            //dispatch notifications to clients with filters on each object
1797:            try {
1798:                transaction = this .getPersistentManager().currentTransaction();
1799:                transaction.begin();
1800:                
1801:                extent = this .getPersistentManager().getExtent(Filter.class, true);
1802:                filter = new String("SELECT Filter FROM Filter f WHERE f.getObject()==virtualElement");
1803:                query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
1804:                filterCollection = (Collection) query.execute();
1805:                
1806:                transaction.commit();
1807:            }
1808:            catch (Exception exception) {
1809:            }
1810:            
1811:            iterator2 = filterCollection.iterator();
1812:            while (iterator2.hasNext()) {
1813:                filter = (Filter) iterator2.next();
1814:                if ((filter.getAccessKind() == Filter.READ_ACCESS) || (filter.getAccessKind() == Filter.READ_WRITE_ACCESS)) {
1815:                    this .sendNotification(filter.getRequester(), virtualElement);
1816:                }
1817:            }
1818:            
1819:            //don't send elements with a blocker
1820:            found = false;
1821:            iterator2 = blockerCollection.iterator();
1822:            while (iterator2.hasNext() && (!found)) {
1823:                found = ((((Blocker)iterator2.next()).getObject()) == virtualElement);
1824:            }
1825:            if (!found) {
1826:                
1827:                //initiate transfer
1828:                if (virtualElement instanceof  BackgroundWorld) {
1829:                    virtualElement.getBackgroundDescription().setApplicationBounds(virtualElement.getBounds());
1830:                    networkElement = new NetworkElement(NetworkElement.NOT_REQUESTED, new Transform3D(), virtualElement.getBackgroundDescription(), virtualElement.getSoundDescription(), virtualElement.getStatus());
1831:                } else {
1832:                    //if virtualElement instanceof ObjectWorld
1833:                    networkElement = new NetworkElement(NetworkElement.NOT_REQUESTED, virtualElement.getTransform3D(), virtualElement.getGeometryDescription(), virtualElement.getSoundDescription(), virtualElement.getStatus());
1834:                }
1835:                networkElement.setInformation(virtualElement.getInformation());
1836:                networkElement.setPrice(virtualElement.getPrice());
1837:                networkElement.setCurrency(virtualElement.getCurrency());
1838:                networkElement.setOthersAccessRights(Avatar.PEERLORD, virtualElement.getOthersAccessRights(Avatar.PEERLORD));
1839:                networkElement.setOthersAccessRights(Avatar.PEER, virtualElement.getOthersAccessRights(Avatar.PEER));
1840:                networkElement.setOthersAccessRights(Avatar.PEERVASSAL, virtualElement.getOthersAccessRights(Avatar.PEERVASSAL));
1841:                networkElement.setOthersAccessRights(Avatar.VASSAL, virtualElement.getOthersAccessRights(Avatar.VASSAL));
1842:                networkElement.setDesignerCapabilities(virtualElement.getDesignerCapabilities());
1843:                
1844:                resultCollection.add(networkElement);
1845:                
1846:            }
1847:            
1848:        }
1849:        
1850:        //keep a reference to objects send
1851:        objectsSend = resultCollection;
1852:        
1853:        //send to network
1854:        return resultCollection;
1855:        
1856:       
1857:    }
1858:    
1859:    //send a notification to a client if a filter is matching
1860:    private NetworkElement sendNotification(Avatar avatar, VirtualElement virtualElement) {
1861:        
1862:        //YYYYYYYYYYYYYYYYYY
1863:         if (avatar.getStatus()==Avatar.NORMAL) {
1864:            
1865:            if (virtualElement instanceof  BackgroundWorld) {
1866:                virtualElement.getBackgroundDescription().setApplicationBounds(virtualElement.getBounds());
1867:                networkElement = new NetworkElement(NetworkElement.NOT_REQUESTED, new Transform3D(), virtualElement.getBackgroundDescription(), virtualElement.getSoundDescription(), virtualElement.getStatus(), virtualElement.hashCode());
1868:            } else {
1869:                //if virtualElement instanceof ObjectWorld
1870:                networkElement = new NetworkElement(NetworkElement.NOT_REQUESTED, virtualElement.getTransform3D(), virtualElement.getGeometryDescription(), virtualElement.getSoundDescription(), virtualElement.getStatus(), virtualElement.hashCode());
1871:            }
1872:            networkElement.setInformation(virtualElement.getInformation());
1873:            networkElement.setPrice(virtualElement.getPrice());
1874:            networkElement.setCurrency(virtualElement.getCurrency());
1875:            networkElement.setOthersAccessRights(Avatar.PEERLORD, virtualElement.getOthersAccessRights(Avatar.PEERLORD));
1876:            networkElement.setOthersAccessRights(Avatar.PEER, virtualElement.getOthersAccessRights(Avatar.PEER));
1877:            networkElement.setOthersAccessRights(Avatar.PEERVASSAL, virtualElement.getOthersAccessRights(Avatar.PEERVASSAL));
1878:            networkElement.setOthersAccessRights(Avatar.VASSAL, virtualElement.getOthersAccessRights(Avatar.VASSAL));
1879:            networkElement.setDesignerCapabilities(virtualElement.getDesignerCapabilities());
1880:            
1881:            return networkElement;
1882:            
1883:        } else {
1884:            return null;
1885:        }
1886:               
1887:    }
1888:    
1889:    //send appearing class
1890:    public NetworkElement sendAdditionNotification(Avatar avatar, Object virtualElement) {
1891:        
1892:        //YYYYYYYYYYYYYYYYYY
1893:        return new NetworkElement(0, new Transform3D(), new Shape3D(), new PointSound(), new Object(), 0);
1894:        
1895:    }
1896:    
1897:    //sends a notification about disappearing objects
1898:    public NetworkElement sendDeletionNotification(Avatar avatar, int oldReference) {
1899:        
1900:         if (avatar.getStatus()==Avatar.NORMAL) {
1901:            
1902:            networkElement = new NetworkElement(NetworkElement.NOT_REQUESTED, null, null, null, null, oldReference);
1903:            networkElement.setInformation(null);
1904:            networkElement.setPrice(null);
1905:            networkElement.setCurrency(null);
1906:            networkElement.setOthersAccessRights(Avatar.PEERLORD, VirtualElement.HIDDEN);
1907:            networkElement.setOthersAccessRights(Avatar.PEER, VirtualElement.HIDDEN);
1908:            networkElement.setOthersAccessRights(Avatar.PEERVASSAL, VirtualElement.HIDDEN);
1909:            networkElement.setOthersAccessRights(Avatar.VASSAL, VirtualElement.HIDDEN);
1910:            networkElement.setDesignerCapabilities(VirtualElement.NO_CAPABILITY);
1911:            
1912:            return networkElement;
1913:            
1914:        } else {
1915:            return null;
1916:        }
1917:        
1918:    }
1919:    
1920:    //we actually don't send every field especially user and designer rights, information, price and currency
1921:    //requestId and status are managed on a different level
1922:    private void sendNetworkElements(HashSet elements) {
1923:        
1924:        BranchGroup branchGroup;
1925:        SceneGraphStreamWriter sceneGraphStreamWriter;
1926:        Iterator iterator;
1927:        NetworkElement networkElement;
1928:        HashMap namedObjects;
1929:        
1930:        sceneGraphStreamWriter = new SceneGraphStreamWriter(objectOutputStream);
1931:        namedObjects = new HashMap();
1932:        branchGroup = new BranchGroup();
1933:        
1934:        while (iterator.hasNext()) {
1935:            networkElement = (NetworkElement) iterator.next();
1936:            transformGroup = new TransformGroup(networkElement.getTransform3D());
1937:            transformGroup.setUserData(networkElement.getReference());
1938:            transformGroup.addChild(networkElement.getGeometryDescription());
1939:            transformGroup.addChild(networkElement.getSoundDescription());
1940:            branchGroup.addChild(transformGroup);
1941:        }
1942:        
1943:        sceneGraphStreamWriter.writeBranchGraph(branchGroup, namedObjects);
1944:        sceneGraphStreamWriter.close();
1945:        
1946:    }
1947:    
1948:    //work out standard request to update objects
1949:    private void workOutRequest(NetworkElement networkElement) {
1950:        
1951:        Transaction transaction;
1952:        Extent extent;
1953:        Query query;
1954:        String filter;
1955:        Collection collection;
1956:        long requestID;
1957:        
1958:        //keep requestID to send replies
1959:        requestID = networkElement.getRequestID();
1960:        
1961:        //react to objects received from client
1962:        try {
1963:            transaction = this .getPersistentManager().currentTransaction();
1964:            transaction.begin();
1965:            
1966:            extent = this .getPersistentManager().getExtent(Avatar.class, true);
1967:            filter = new String("SELECT VirtualElement FROM VirtualElement v WHERE v.hashCode()==networkElement.getObjectReference()");
1968:            query = this .getPersistentManager().newQuery(Avatar.class, extent, filter);
1969:            collection = (Collection) query.execute();
1970:            
1971:            transaction.commit();
1972:        }
1973:        catch (Exception exception) {
1974:        }
1975:        
1976:        collection = this .filterCollection(collection);
1977:        if (collection.size()!=0) {
1978:            //just take the first one that is writable by the user
1979:            virtualElement = (VirtualElement) iterator.next();
1980:            //hashCode should be unique but who knows ?
1981:            //XXXXXX
1982:            //we reuse every non null field send by the user
1983:            if (networkElement.getTransform3D()!=null) {
1984:                virtualElement.setTransform3D(networkElement.getTransform3D());
1985:            }
1986:            if (networkElement.getGeometryDescription()!=null) {
1987:                virtualElement.setGeometryDescription(networkElement.getGeometryDescription());
1988:            }
1989:            if (networkElement.getSoundDescription()!=null) {
1990:                virtualElement.setSoundDescription(networkElement.getSoundDescription());
1991:            }
1992:            if (networkElement.getStatus()!=null) {
1993:                virtualElement.setStatus(networkElement.getStatus());
1994:            }
1995:        }
1996:        //else {
1997:        //object has been deleted or reference is corrupted
1998:        //get rid of this message
1999:        //}
2000:        
2001:        //try to set the avatar to the desired position
2002:        if (avatar.getSkin()!=null) {
2003:            avatar.getSkin().setTransform3D(clientInformation.getPosition());
2004:            clientInformation.setPosition(avatar.getSkin().getTransform3D());
2005:        }
2006:        
2007:        //use the client scope
2008:        boundingSphere = new BoundingSphere(clientInformation.getPosition(), clientInformation.getDrawingRadius());
2009:        
2010:        //get land the avatar is on
2011:        try {
2012:            transaction = this .getPersistentManager().currentTransaction();
2013:            transaction.begin();
2014:            
2015:            extent = this .getPersistentManager().getExtent(Filter.class, true);
2016:            filter = new String("SELECT Land FROM Land l WHERE l.getBounds().intersects(boundingSphere)");
2017:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2018:            collection = (Collection) query.execute();
2019:            
2020:            transaction.commit();
2021:        }
2022:        catch (Exception exception) {
2023:        }
2024:        
2025:        positionAsPoint = new Point3d();
2026:        position.get(positionAsPoint);
2027:        found = false;
2028:        iterator = collection.iterator();
2029:        while (iterator.hasNext() && (!found)) {
2030:            found = ((Land)iterator.next()).getBounds().intersect(positionAsPoint);
2031:        }
2032:        
2033:        //whether in his home or on someone's land, this land should be navigable for that user because of the previous setTransform
2034:        land.doEnter(avatar);
2035:        
2036:        simpleCollection = new Collection(collection);
2037:        simpleCollection.remove(land);
2038:        iterator = simpleCollection.iterator();
2039:        while (iterator.hasNext()) {
2040:            ((Land)iterator.next()).doLook(avatar);
2041:        }
2042:        
2043:        //get and display stuff depending on land capabilities
2044:        
2045:        //select matching BackgroundWorlds from bounds and capabilities
2046:        try {
2047:            transaction = this .getPersistentManager().currentTransaction();
2048:            transaction.begin();
2049:            
2050:            extent = this .getPersistentManager().getExtent(Filter.class, true);
2051:            filter = new String("SELECT BackgroundWorld FROM BackgroundWorld b WHERE b.getGeometryBounds().intersects(boundingSphere)");
2052:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2053:            collection1 = (Collection) query.execute();
2054:            
2055:            transaction.commit();
2056:        }
2057:        catch (Exception exception) {
2058:        }
2059:        
2060:        //select matching ObjectWorlds from bounds and capabilities
2061:        try {
2062:            transaction = this .getPersistentManager().currentTransaction();
2063:            transaction.begin();
2064:            
2065:            extent = this .getPersistentManager().getExtent(Filter.class, true);
2066:            filter = new String("SELECT ObjectWorld FROM ObjectWorld o WHERE o.getGeometryBounds().intersects(boundingSphere)");
2067:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2068:            collection2 = (Collection) query.execute();
2069:            
2070:            transaction.commit();
2071:        }
2072:        catch (Exception exception) {
2073:        }
2074:        
2075:        collection = this .filterCollection(avatar, collection1.addAll(collection2));
2076:        
2077:        //find blockers
2078:        try {
2079:            transaction = this .getPersistentManager().currentTransaction();
2080:            transaction.begin();
2081:            
2082:            extent = this .getPersistentManager().getExtent(Filter.class, true);
2083:            filter = new String("SELECT Blocker FROM Blocker b WHERE b.getRequester()==avatar");
2084:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2085:            blockerCollection = (Collection) query.execute();
2086:            
2087:            transaction.commit();
2088:        }
2089:        catch (Exception exception) {
2090:        }
2091:        
2092:        //don't send blockers
2093:        
2094:        iterator = collection.iterator();
2095:        resultCollection = new HashSet();
2096:        while (iterator.hasNext()) {
2097:            virtualElement = (VirtualElement) iterator.next();
2098:            
2099:            virtualElement.doVisible();
2100:            virtualElement.doSonore();
2101:            
2102:            //dispatch notifications to clients with filters on each object
2103:            try {
2104:                transaction = this .getPersistentManager().currentTransaction();
2105:                transaction.begin();
2106:                
2107:                extent = this .getPersistentManager().getExtent(Filter.class, true);
2108:                filter = new String("SELECT Filter FROM Filter f WHERE f.getObject()==virtualElement");
2109:                query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2110:                filterCollection = (Collection) query.execute();
2111:                
2112:                transaction.commit();
2113:            }
2114:            catch (Exception exception) {
2115:            }
2116:            
2117:            iterator2 = filterCollection.iterator();
2118:            while (iterator2.hasNext()) {
2119:                filter = (Filter) iterator2.next();
2120:                if ((filter.getAccessKind() == Filter.READ_ACCESS) || (filter.getAccessKind() == Filter.READ_WRITE_ACCESS)) {
2121:                    this .sendNotification(filter.getRequester(), virtualElement);
2122:                }
2123:            }
2124:            
2125:            //don't send elements with a blocker
2126:            found = false;
2127:            iterator2 = blockerCollection.iterator();
2128:            while (iterator2.hasNext() && (!found)) {
2129:                found = ((((Blocker)iterator2.next()).getObject()) == virtualElement);
2130:            }
2131:            if (!found) {
2132:                
2133:                //initiate transfer
2134:                if (virtualElement instanceof  BackgroundWorld) {
2135:                    virtualElement.getBackgroundDescription().setApplicationBounds(virtualElement.getBounds());
2136:                    networkElement = new NetworkElement(requestID, new Transform3D(), virtualElement.getBackgroundDescription(), virtualElement.getSoundDescription(), virtualElement.getStatus());
2137:                } else {
2138:                    //if virtualElement instanceof ObjectWorld
2139:                    networkElement = new NetworkElement(requestID, virtualElement.getTransform3D(), virtualElement.getGeometryDescription(), virtualElement.getSoundDescription(), virtualElement.getStatus());
2140:                }
2141:                networkElement.setInformation(virtualElement.getInformation());
2142:                networkElement.setPrice(virtualElement.getPrice());
2143:                networkElement.setCurrency(virtualElement.getCurrency());
2144:                networkElement.setOthersAccessRights(Avatar.PEERLORD, virtualElement.getOthersAccessRights(Avatar.PEERLORD));
2145:                networkElement.setOthersAccessRights(Avatar.PEER, virtualElement.getOthersAccessRights(Avatar.PEER));
2146:                networkElement.setOthersAccessRights(Avatar.PEERVASSAL, virtualElement.getOthersAccessRights(Avatar.PEERVASSAL));
2147:                networkElement.setOthersAccessRights(Avatar.VASSAL, virtualElement.getOthersAccessRights(Avatar.VASSAL));
2148:                networkElement.setDesignerCapabilities(virtualElement.getDesignerCapabilities());
2149:                
2150:                resultCollection.add(networkElement);
2151:                
2152:            }
2153:            
2154:        }
2155:        
2156:        //only send updated objects and requested objects
2157:        iterator = resultCollection.iterator();
2158:        
2159:        while (iterator.hasNext()) {
2160:            networkElement = (NetworkElement) iterator.next();
2161:            if (sendObject.contains(networkElement)) {
2162:                
2163:            }
2164:        }
2165:        
2166:        //sendObjects;
2167:        //YYYYYYYY XXX
2168:       // virtualElement.setCaller();
2169:        //YYYYYYYY XXXX
2170:        
2171:        //YYYYYYYY XXXX //manage disappearing objects doInvisible() doUnSonore()
2172:        
2173:        //YYYYYYYY  XXXx //manage doUnLook
2174:        
2175:        //update objects depending on client change or dirty objects from other client access
2176:        
2177:        //clear dirty when every client has had a round
2178:        
2179:        try {
2180:            transaction = this .getPersistentManager().currentTransaction();
2181:            transaction.begin();
2182:            
2183:            extent = this .getPersistentManager().getExtent(Filter.class, true);
2184:            filter = new String("SELECT BackgroundWorld FROM BackgroundWorld b WHERE b.getDirty()==true AND b.getGeometryBounds().intersects(boundingSphere)");
2185:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2186:            collection1 = (Collection) query.execute();
2187:            
2188:            transaction.commit();
2189:        }
2190:        catch (Exception exception) {
2191:        }
2192:        
2193:        try {
2194:            transaction = this .getPersistentManager().currentTransaction();
2195:            transaction.begin();
2196:            
2197:            extent = this .getPersistentManager().getExtent(Filter.class, true);
2198:            filter = new String("SELECT ObjectWorld FROM ObjectWorld o WHERE o.getDirty()==true AND o.getGeometryBounds().intersects(boundingSphere)");
2199:            query = this .getPersistentManager().newQuery(Filter.class, extent, filter);
2200:            collection2 = (Collection) query.execute();
2201:            
2202:            transaction.commit();
2203:        }
2204:        catch (Exception exception) {
2205:        }
2206:        
2207:        collection1.addAll(collection2);
2208:        
2209:        //build results and clear dirty state
2210:        
2211:        while (iterator.hasNext()) {
2212:            ((VirtualElement)iterator.next()).clearDirty();
2213:        }
2214:        
2215:        try {
2216:            transaction = this .getPersistenceManager().currentTransaction();
2217:            transaction.begin();
2218:            
2219:            this .getPersistentManager().refreshAll(collection);
2220:            
2221:            transaction.commit();
2222:        }
2223:        catch (Exception exception) {
2224:        }
2225:        
2226:        //send to network
2227:        return resultCollection;
2228:    }
2229:    
2230:    private static ServerSocketFactory getServerSocketFactory(String type) {
2231:        
2232:        SSLContext sSLContext;
2233:        KeyManagerFactory keyManagerFactory;
2234:        KeyStore keyStore;
2235:        char[] passphrase;
2236:        SSLServerSocketFactory sSLServerSocketFactory;
2237:        
2238:        if (type.equals("TLS")) {
2239:            try {
2240:                // set up key manager to do server authentication
2241:                passphrase = "passphrase".toCharArray();
2242:                
2243:                sSLContext = SSLContext.getInstance("TLS");
2244:                keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
2245:                keyStore = KeyStore.getInstance("JKS");
2246:                
2247:                keyStore.load(new FileInputStream("testkeys"), passphrase);
2248:                keyManagerFactory.init(keyStore, passphrase);
2249:                sSLContext.init(keyManagerFactory.getKeyManagers(), null, null);
2250:                
2251:                sSLServerSocketFactory = sSLContext.getServerSocketFactory();
2252:                return sSLServerSocketFactory;
2253:            } catch (Exception exception) {
2254:                exception.printStackTrace();
2255:            }
2256:        } else {
2257:            return ServerSocketFactory.getDefault();
2258:        }
2259:        return null;
2260:        
2261:    }
2262:    
2263:    
2264:    public boolean getActiveLog() {
2265:        
2266:        return activeLog;
2267:        
2268:    }
2269:    
2270:    public void setActiveLog(boolean log) {
2271:        
2272:        activeLog = log;
2273:        
2274:    }
2275:    
2276:    public void log(String string) {
2277:        
2278:        if (activeLog) {
2279:            System.out.println(string);
2280:        }
2281:        
2282:    }
2283:    
2284:    private final static HashSet filterCollection(Avatar caller, Collection collection) {
2285:        
2286:        Iterator iterator;
2287:        Iterator iterator2;
2288:        Collection passCollection;
2289:        HashSet resultCollection;
2290:        int relation;
2291:        VirtualElement virtualElement;
2292:        boolean found;
2293:        Pass pass;
2294:        
2295:        resultCollection = new HashSet();
2296:        
2297:        if (caller!=null) {
2298:            
2299:            //objects with a pass may bypass access
2300:            passCollection = caller.getPass();
2301:            
2302:            iterator = collection.iterator();
2303:            
2304:            while (iterator.hasNext()) {
2305:                
2306:                virtualElement = (VirtualElement) iterator.next();
2307:                relation = Avatar.getFeudalRelation(caller, virtualElement.getUserOwner());
2308:                
2309:                if ((relation == Avatar.LORD) || (relation == Avatar.SELF)) {
2310:                    resultCollection.add(virtualElement);
2311:                } else {
2312:                    if (virtualElement.getOthersAccessRights(relation) != VirtualElement.HIDDEN) {
2313:                        resultCollection.add(virtualElement);
2314:                    } else {
2315:                        iterator2 = passCollection.iterator();
2316:                        found = false;
2317:                        while (iterator2.hasNext() && (!found)) {
2318:                            pass = (Pass) iterator2.next();
2319:                            found = (pass.getObject() == virtualElement);
2320:                        }
2321:                        if (found) {
2322:                            resultCollection.add(virtualElement);
2323:                        }
2324:                    }
2325:                }
2326:                
2327:            }
2328:            
2329:        }
2330:        
2331:        return resultCollection;
2332:        
2333:    }
2334:    
2335:}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.