1 /*
   2  * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.corba.se.impl.activation;
  27 
  28 import java.io.File;
  29 import java.io.FileInputStream;
  30 import java.io.FileOutputStream;
  31 import java.io.ObjectInputStream;
  32 import java.io.ObjectOutputStream;
  33 import java.io.Serializable;
  34 import java.util.Properties;
  35 import java.util.Hashtable;
  36 import java.util.Enumeration;
  37 import java.util.Vector;
  38 
  39 import org.omg.CORBA.CompletionStatus;
  40 import org.omg.CORBA.INITIALIZE;
  41 import org.omg.CORBA.INTERNAL;
  42 import org.omg.CORBA.SystemException;
  43 
  44 import com.sun.corba.se.spi.activation.BadServerDefinition;
  45 import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;
  46 import com.sun.corba.se.spi.activation._RepositoryImplBase;
  47 import com.sun.corba.se.spi.activation.ServerAlreadyRegistered;
  48 import com.sun.corba.se.spi.activation.ServerAlreadyInstalled;
  49 import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled;
  50 import com.sun.corba.se.spi.activation.ServerNotRegistered;
  51 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
  52 import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
  53 import com.sun.corba.se.spi.orb.ORB;
  54 import com.sun.corba.se.impl.orbutil.ORBConstants;
  55 
  56 import com.sun.corba.se.spi.logging.CORBALogDomains;
  57 import com.sun.corba.se.impl.logging.ActivationSystemException;
  58 
  59 /**
  60  *
  61  * @author      Rohit Garg
  62  * @since       JDK1.2
  63  */
  64 public class RepositoryImpl extends _RepositoryImplBase
  65     implements Serializable
  66 {
  67 
  68     // added serialver computed by the tool
  69     private static final long serialVersionUID = 8458417785209341858L;
  70 
  71     RepositoryImpl(ORB orb, File dbDir, boolean debug)
  72     {
  73         this.debug = debug ;
  74         this.orb = orb;
  75         wrapper = ActivationSystemException.get( orb, CORBALogDomains.ORBD_REPOSITORY ) ;
  76 
  77         // if databse does not exist, create it otherwise read it in
  78         File dbFile = new File(dbDir, "servers.db");
  79         if (!dbFile.exists()) {
  80             db = new RepositoryDB(dbFile);
  81             db.flush();
  82         } else {
  83             try {
  84                 FileInputStream fis = new FileInputStream(dbFile);
  85                 ObjectInputStream ois = new ObjectInputStream(fis);
  86                 db = (RepositoryDB) ois.readObject();
  87                 ois.close();
  88             } catch (Exception e) {
  89                 throw wrapper.cannotReadRepositoryDb( e ) ;
  90             }
  91         }
  92 
  93         // export the repository
  94         orb.connect(this);
  95     }
  96 
  97     private String printServerDef( ServerDef sd )
  98     {
  99         return "ServerDef[applicationName=" + sd.applicationName +
 100             " serverName=" + sd.serverName +
 101             " serverClassPath=" + sd.serverClassPath +
 102             " serverArgs=" + sd. serverArgs +
 103             " serverVmArgs=" + sd.serverVmArgs +
 104             "]" ;
 105     }
 106 
 107     public int registerServer(ServerDef serverDef, int theServerId)
 108         throws ServerAlreadyRegistered
 109     {
 110         int         serverId;
 111         DBServerDef server = null;
 112 
 113         synchronized (db) {
 114 
 115             // check if server already registered
 116             Enumeration enumeration = db.serverTable.elements();
 117             while (enumeration.hasMoreElements()) {
 118                 server = (DBServerDef) enumeration.nextElement();
 119                 if (serverDef.applicationName.equals(server.applicationName)) {
 120                     if (debug)
 121                         System.out.println(
 122                             "RepositoryImpl: registerServer called " +
 123                             "to register ServerDef " +
 124                             printServerDef( serverDef ) +
 125                             " with " + ((theServerId==illegalServerId) ?
 126                         "a new server Id" : ("server Id " + theServerId)) +
 127                                            " FAILED because it is already registered." ) ;
 128 
 129                     throw (new ServerAlreadyRegistered(server.id));
 130                 }
 131             }
 132 
 133             // generate a new server id
 134             if (theServerId == illegalServerId)
 135                 serverId = db.incrementServerIdCounter();
 136             else
 137                 serverId = theServerId;
 138 
 139             // add server def to the database
 140             server = new DBServerDef(serverDef, serverId);
 141             db.serverTable.put(new Integer(serverId), server);
 142             db.flush();
 143 
 144             if (debug)
 145                 if (theServerId==illegalServerId)
 146                     System.out.println( "RepositoryImpl: registerServer called " +
 147                                         "to register ServerDef " + printServerDef( serverDef ) +
 148                                         " with new serverId " + serverId ) ;
 149                 else
 150                     System.out.println( "RepositoryImpl: registerServer called " +
 151                                         "to register ServerDef " + printServerDef( serverDef ) +
 152                                         " with assigned serverId " + serverId ) ;
 153 
 154             return serverId;
 155         }
 156     }
 157 
 158     public int registerServer(ServerDef serverDef)
 159         throws ServerAlreadyRegistered, BadServerDefinition
 160     {
 161         // verify that the entry is valid
 162         LegacyServerSocketEndPointInfo endpoint =
 163             orb.getLegacyServerSocketManager()
 164                 .legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING);
 165         int initSvcPort = ((SocketOrChannelAcceptor)endpoint)
 166             .getServerSocket().getLocalPort();
 167         ServerTableEntry entry = new ServerTableEntry( wrapper,
 168             illegalServerId, serverDef, (int) initSvcPort, "", true, debug );
 169 
 170         switch (entry.verify()) {
 171         case ServerMain.OK:
 172             break;
 173         case ServerMain.MAIN_CLASS_NOT_FOUND:
 174             throw new BadServerDefinition("main class not found.");
 175         case ServerMain.NO_MAIN_METHOD:
 176             throw new BadServerDefinition("no main method found.");
 177         case ServerMain.APPLICATION_ERROR:
 178             throw new BadServerDefinition("server application error.");
 179         default:
 180             throw new BadServerDefinition("unknown Exception.");
 181         }
 182 
 183         return registerServer(serverDef, illegalServerId);
 184     }
 185 
 186     public void unregisterServer(int serverId) throws ServerNotRegistered {
 187 
 188         DBServerDef server = null;
 189         Integer id = new Integer(serverId);
 190 
 191         synchronized (db) {
 192 
 193             // check to see if the server is registered
 194             server = (DBServerDef) db.serverTable.get(id);
 195             if (server == null)  {
 196                 if (debug)
 197                     System.out.println(
 198                                        "RepositoryImpl: unregisterServer for serverId " +
 199                                        serverId + " called: server not registered" ) ;
 200 
 201                 throw (new ServerNotRegistered());
 202             }
 203 
 204             // remove server from the database
 205             db.serverTable.remove(id);
 206             db.flush();
 207         }
 208 
 209         if (debug)
 210             System.out.println(
 211                                "RepositoryImpl: unregisterServer for serverId " + serverId +
 212                                " called" ) ;
 213     }
 214 
 215     private DBServerDef getDBServerDef(int serverId) throws ServerNotRegistered
 216     {
 217         Integer id = new Integer(serverId);
 218         DBServerDef server = (DBServerDef) db.serverTable.get(id);
 219 
 220         if (server == null)
 221             throw new ServerNotRegistered( serverId );
 222 
 223         return server ;
 224     }
 225 
 226     public ServerDef getServer(int serverId) throws ServerNotRegistered
 227     {
 228         DBServerDef server = getDBServerDef( serverId ) ;
 229 
 230         ServerDef serverDef = new ServerDef(server.applicationName, server.name,
 231                                             server.classPath, server.args, server.vmArgs);
 232 
 233         if (debug)
 234             System.out.println(
 235                                "RepositoryImpl: getServer for serverId " + serverId +
 236                                " returns " + printServerDef( serverDef ) ) ;
 237 
 238         return serverDef;
 239     }
 240 
 241     public boolean isInstalled(int serverId) throws ServerNotRegistered {
 242         DBServerDef server = getDBServerDef( serverId ) ;
 243         return server.isInstalled ;
 244     }
 245 
 246     public void install( int serverId )
 247         throws ServerNotRegistered, ServerAlreadyInstalled
 248     {
 249         DBServerDef server = getDBServerDef( serverId ) ;
 250 
 251         if (server.isInstalled)
 252             throw new ServerAlreadyInstalled( serverId ) ;
 253         else {
 254             server.isInstalled = true ;
 255             db.flush() ;
 256         }
 257     }
 258 
 259     public void uninstall( int serverId )
 260         throws ServerNotRegistered, ServerAlreadyUninstalled
 261     {
 262         DBServerDef server = getDBServerDef( serverId ) ;
 263 
 264         if (!server.isInstalled)
 265             throw new ServerAlreadyUninstalled( serverId ) ;
 266         else {
 267             server.isInstalled = false ;
 268             db.flush() ;
 269         }
 270     }
 271 
 272     public int[] listRegisteredServers() {
 273         synchronized (db) {
 274             int i=0;
 275 
 276             int servers[] = new int[db.serverTable.size()];
 277 
 278             Enumeration enumeration = db.serverTable.elements();
 279 
 280             while (enumeration.hasMoreElements()) {
 281                 DBServerDef server = (DBServerDef) enumeration.nextElement();
 282                 servers[i++] = server.id;
 283             }
 284 
 285             if (debug) {
 286                 StringBuffer sb = new StringBuffer() ;
 287                 for (int ctr=0; ctr<servers.length; ctr++) {
 288                     sb.append( ' ' ) ;
 289                     sb.append( servers[ctr] ) ;
 290                 }
 291 
 292                 System.out.println(
 293                                    "RepositoryImpl: listRegisteredServers returns" +
 294                                    sb.toString() ) ;
 295             }
 296 
 297             return servers;
 298         }
 299     }
 300 
 301     public int getServerID(String applicationName) throws ServerNotRegistered {
 302         synchronized (db) {
 303             int result = -1 ;
 304 
 305             for (Enumeration serverIds = db.serverTable.keys();
 306                  serverIds.hasMoreElements();)
 307                 {
 308                     Integer nextServerId = (Integer) serverIds.nextElement();
 309                     DBServerDef dbServerDef =
 310                         (DBServerDef) db.serverTable.get(nextServerId);
 311 
 312                     if (dbServerDef.applicationName.equals(applicationName)) {
 313                         result = nextServerId.intValue();
 314                         break ;
 315                     }
 316                 }
 317 
 318             if (debug)
 319                 System.out.println("RepositoryImpl: getServerID for " +
 320                                    applicationName + " is " + result ) ;
 321 
 322             if (result == -1) {
 323                 throw (new ServerNotRegistered());
 324             } else {
 325                 return result ;
 326             }
 327         }
 328     }
 329 
 330     public String[] getApplicationNames() {
 331         synchronized (db) {
 332             Vector v = new Vector();
 333             for (Enumeration serverIds = db.serverTable.keys();
 334                  serverIds.hasMoreElements();)
 335                 {
 336                     Integer nextServerId = (Integer) serverIds.nextElement();
 337 
 338                     DBServerDef dbServerDef = (DBServerDef)db.serverTable.get(
 339                                                                               nextServerId);
 340 
 341                     if (!dbServerDef.applicationName.equals(""))
 342                         v.addElement( dbServerDef.applicationName ) ;
 343                 }
 344 
 345             String[] apps = new String[v.size()];
 346             for (int i = 0; i < v.size(); i++) {
 347                 apps[i] = (String)v.elementAt(i);
 348             }
 349 
 350             if (debug) {
 351                 StringBuffer sb = new StringBuffer() ;
 352                 for (int ctr=0; ctr<apps.length; ctr++) {
 353                     sb.append( ' ' ) ;
 354                     sb.append( apps[ctr] ) ;
 355                 }
 356 
 357                 System.out.println( "RepositoryImpl: getApplicationNames returns " +
 358                                     sb.toString() ) ;
 359             }
 360 
 361             return apps;
 362         }
 363     }
 364     /**
 365      * Typically the Repositoy is created within the ORBd VM but it can
 366      * be independently started as well.
 367      */
 368     public static void main(String args[]) {
 369         boolean debug = false ;
 370         for (int ctr=0; ctr<args.length; ctr++)
 371             if (args[ctr].equals("-debug"))
 372                 debug = true ;
 373 
 374         try {
 375             // See Bug 4396928 for more information about why we are
 376             // initializing the ORBClass to PIORB (now ORBImpl, but see the bug).
 377             Properties props = new Properties();
 378             props.put("org.omg.CORBA.ORBClass",
 379                 "com.sun.corba.se.impl.orb.ORBImpl");
 380             ORB orb = (ORB) ORB.init(args, props);
 381 
 382             // create the repository object
 383             String db = System.getProperty( ORBConstants.DB_PROPERTY,
 384                     ORBConstants.DEFAULT_DB_NAME );
 385             RepositoryImpl repository = new RepositoryImpl(orb, new File(db),
 386                                                            debug);
 387 
 388             // wait for shutdown
 389             orb.run();
 390         } catch (Exception ex) {
 391             ex.printStackTrace();
 392         }
 393     }
 394 
 395     transient private boolean debug = false;
 396 
 397     final static int illegalServerId = -1;
 398 
 399     transient private RepositoryDB db = null;
 400 
 401     transient ORB orb = null;
 402 
 403     transient ActivationSystemException wrapper ;
 404 
 405     class RepositoryDB implements Serializable
 406     {
 407         File            db;
 408         Hashtable       serverTable;
 409         Integer         serverIdCounter;
 410 
 411         RepositoryDB(File dbFile) {
 412 
 413             db = dbFile;
 414 
 415             // initialize the Server Id counter and hashtable.
 416             // the lower id range is reserved for system servers
 417             serverTable     = new Hashtable(255);
 418             serverIdCounter = new Integer(256);
 419         }
 420 
 421         int incrementServerIdCounter()
 422         {
 423             int value = serverIdCounter.intValue();
 424             serverIdCounter = new Integer(++value);
 425 
 426             return value;
 427         }
 428 
 429         void flush()
 430         {
 431             try {
 432                 db.delete();
 433                 FileOutputStream fos = new FileOutputStream(db);
 434                 ObjectOutputStream oos = new ObjectOutputStream(fos);
 435                 oos.writeObject(this);
 436                 oos.flush();
 437                 oos.close();
 438             } catch (Exception ex) {
 439                 throw wrapper.cannotWriteRepositoryDb( ex ) ;
 440             }
 441         }
 442     }
 443 
 444     class DBServerDef implements Serializable
 445     {
 446         public String toString() {
 447             return "DBServerDef(applicationName=" + applicationName +
 448                 ", name=" + name +
 449                 ", classPath=" + classPath +
 450                 ", args=" + args +
 451                 ", vmArgs=" + vmArgs +
 452                 ", id=" + id +
 453                 ", isInstalled=" + isInstalled + ")" ;
 454         }
 455 
 456         DBServerDef(ServerDef server, int server_id) {
 457             applicationName     = server.applicationName ;
 458             name        = server.serverName;
 459             classPath   = server.serverClassPath;
 460             args        = server.serverArgs;
 461             vmArgs      = server.serverVmArgs;
 462             id          = server_id;
 463             isInstalled = false ;
 464         }
 465 
 466         String applicationName;
 467         String name;
 468         String classPath;
 469         String args;
 470         String vmArgs;
 471         boolean isInstalled ;
 472         int    id;
 473     }
 474 }