Package com.sun.jini.start

Source Code of com.sun.jini.start.SharedGroupImpl$DestroyThread

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.jini.start;

import net.jini.activation.ActivationExporter;
import net.jini.config.Configuration;
import net.jini.config.ConfigurationProvider;
import net.jini.config.ConfigurationException;
import net.jini.core.constraint.RemoteMethodControl;
import net.jini.export.Exporter;
import net.jini.export.ProxyAccessor;
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.tcp.TcpServerEndpoint;
import net.jini.security.BasicProxyPreparer;
import net.jini.security.ProxyPreparer;
import net.jini.security.TrustVerifier;
import net.jini.security.proxytrust.ServerProxyTrust;

import java.rmi.MarshalledObject;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.activation.ActivationGroup;
import java.rmi.activation.ActivationID;
import java.rmi.activation.ActivationSystem;
import java.rmi.activation.ActivationException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;

/**
* The provided implementation
* of the {@link SharedGroup} service.
*
* The following items are discussed below:
* <ul>
* <li><a href="#configEntries">Configuring SharedGroupImpl</a>
* <li><a href="#logging">Logging</a>
* </ul>
*
* <a name="configEntries">
* <h3>Configuring SharedGroupImpl</h3>
* </a>
*
* This implementation of <code>SharedGroupImpl</code> supports the
* following configuration entries, with component
* <code>com.sun.jini.start</code>:
*
*   <table summary="Describes the activationIdPreparer configuration entry"
*          border="0" cellpadding="2">
*     <tr valign="top">
*       <th scope="col" summary="layout"> <font size="+1">&#X2022;</font>
*       <th scope="col" align="left" colspan="2"> <font size="+1"><code>
*       activationIdPreparer</code></font>
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Type: <td> {@link net.jini.security.ProxyPreparer}
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Default: <td> <code>
*         new {@link net.jini.security.BasicProxyPreparer}()
*         </code>
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Description: <td> The proxy preparer for the service's activation
*       ID. The value should not be <code>null</code>.
*
*       The service starter calls the 
*       {@link java.rmi.activation.ActivationID#activate
*       activate} method to activate the service.
*   </table>
*
*   <table summary="Describes the activationSystemPreparer configuration
*          entry"
*          border="0" cellpadding="2">
*     <tr valign="top">
*       <th scope="col" summary="layout"> <font size="+1">&#X2022;</font>
*       <th scope="col" align="left" colspan="2"> <font size="+1"><code>
*       activationSystemPreparer</code></font>
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Type: <td> {@link net.jini.security.ProxyPreparer}
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Default: <td> <code>
*         new {@link net.jini.security.BasicProxyPreparer}()</code>
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Description: <td> The proxy preparer for the proxy for the
*       activation system. The value should not be <code>null</code>. This
*       entry is obtained at service start and restart.
*
*       The service calls the {@link
*       java.rmi.activation.ActivationSystem#unregisterGroup
*       unregisterGroup} method on the {@link
*       java.rmi.activation.ActivationSystem} upon service destruction.
*   </table>
*
*   <table summary="Describes the exporter configuration entry"
*          border="0" cellpadding="2">
*     <tr valign="top">
*       <th scope="col" summary="layout"> <font size="+1">&#X2022;</font>
*       <th scope="col" align="left" colspan="2"> <font size="+1"><code>
*       exporter</code></font>
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Type: <td> {@link net.jini.export.Exporter}
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Default: <td>
* <pre>
* new {@link net.jini.activation.ActivationExporter}(
*     <i>activationID</i>,
*     new {@link net.jini.jeri.BasicJeriExporter}(
*         {@link net.jini.jeri.tcp.TcpServerEndpoint#getInstance TcpServerEndpoint.getInstance}(0),
*         new {@link net.jini.jeri.BasicILFactory}(), false, true))
* </pre>
*     <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*       Description: <td> The object to use for exporting the service. The
*       value should not be <code>null</code>. The call to
*       <code>getEntry</code> will supply the activation ID in
*       the <code>data</code> argument. This entry is obtained at service
*       start and restart.
*   </table> <p>
*   <table summary="Describes the loginContext configuration entry"
*     border="0" cellpadding="2">
*   <tr valign="top">
*     <th scope="col" summary="layout"> <font size="+1">&#X2022;</font>
*     <th scope="col" align="left" colspan="2"> <font size="+1"><code>
*   loginContext</code></font>
*   <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*     Type: <td> {@link javax.security.auth.login.LoginContext}
*   <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*     Default: <td> <code>null</code>
*   <tr valign="top"> <td> &nbsp <th scope="row" align="right">
*     Description: <td> If not <code>null</code>, specifies the JAAS
*     login context to use for performing a JAAS login and supplying the
*     {@link javax.security.auth.Subject} to use when running the
*     service. If <code>null</code>, no JAAS login is performed. This
*     entry is obtained at service start and restart.
*   </table>
*
*
*<a name="logging">
*<h3>Loggers and Logging Levels</h3>
*</a>
*
*The SharedGroupImpl service implementation uses the {@link
*java.util.logging.Logger}, named <code>com.sun.jini.sharedGroup</code>.
*The following table describes the
*type of information logged as well as the levels of information logged.
*<p>
*
<table border="1" cellpadding="5"
*   summary="Describes logging performed by sharedGroup at different
*   logging levels">
*
<caption halign="center" valign="top"><b><code>
*     com.sun.jini.start.sharedGroup</code></b></caption>
*
<tr> <th scope="col"> Level <th scope="col"> Description
*
<tr> <td> {@link java.util.logging.Level#FINE FINE} <td>
*    for low level
*    service operation tracing
<tr> <td> {@link java.util.logging.Level#FINER FINER} <td>
*    for lower level
*    service operation tracing
<tr> <td> {@link java.util.logging.Level#FINEST FINEST} <td>
*    for lowest level
*    service operation tracing
*
</table> <p>
*
* @author Sun Microsystems, Inc.
*
*/
public class SharedGroupImpl
    implements SharedGroupBackEnd, ServerProxyTrust, ProxyAccessor
{

    /** Component name for configuration entries */
    private static final String START_PACKAGE = "com.sun.jini.start";

    /** Configure logger */
    private static final Logger logger =
        Logger.getLogger(START_PACKAGE + ".sharedGroup");

    /** Our prepared activation ID reference */
    private ActivationID activationID = null;

    /** The prepared activation system reference */
    private ActivationSystem activationSystem;
   
    /** The inner proxy of this server */
    private Remote ourStub;

    /** <code>LoginContext</code> for this service. */
    private final LoginContext loginContext;
   
    /** The exporter for exporting and unexporting */
    protected Exporter exporter;

    /**
     * Activation constructor.
     */
    private SharedGroupImpl(ActivationID activationID, MarshalledObject data)
  throws Exception
    {
  logger.entering(SharedGroupImpl.class.getName(), "SharedGroupImpl",
            new Object[] { activationID, data});
  this.activationID = activationID;
        try {
            String[] configArgs = (String[])data.get()
            final Configuration config =
                ConfigurationProvider.getInstance(configArgs);
            loginContext = (LoginContext) config.getEntry(
                START_PACKAGE, "loginContext", LoginContext.class, null);
            if (loginContext != null) {
                doInitWithLogin(config, loginContext);
            } else {
                doInit(config);
            }
  } catch (Exception e) {
            cleanup();
      throw e;
  }
  logger.exiting(SharedGroupImpl.class.getName(), "SharedGroupImpl");
    }

    private void doInitWithLogin(final Configuration config,
        LoginContext loginContext) throws Exception
    {
        loginContext.login();
        try {
            Subject.doAsPrivileged(
                loginContext.getSubject(),
                new PrivilegedExceptionAction() {
                    public Object run() throws Exception {
                        doInit(config);
                        return null;
                    }
                },
                null);
        } catch (PrivilegedActionException e) {
            throw e.getException();
        }
    }
   
    private void doInit(Configuration config) throws Exception {
        ProxyPreparer activationSystemPreparer =
            (ProxyPreparer) config.getEntry(
                START_PACKAGE, "activationSystemPreparer",
                ProxyPreparer.class, new BasicProxyPreparer());
  if (activationSystemPreparer == null) {
             throw new ConfigurationException(START_PACKAGE
       + ".activationSystemPreparer entry should not be null");
        }
        logger.log(Level.FINE, START_PACKAGE + ".activationSystemPreparer: {0}",
            activationSystemPreparer);
     
  ProxyPreparer activationIdPreparer = (ProxyPreparer)
      config.getEntry(START_PACKAGE, "activationIdPreparer",
      ProxyPreparer.class, new BasicProxyPreparer());
  if (activationIdPreparer == null) {
             throw new ConfigurationException(START_PACKAGE
       + ".activationIdPreparer entry should not be null");
        }
        logger.log(Level.FINE, START_PACKAGE + ".activationIdPreparer: {0}",
            activationIdPreparer);
     
        // Prepare activation subsystem
  /*
   * ActivationGroup is trusted and returned ActivationSystem
   * might already have been prepared by the group itself.
   */
  activationSystem = (ActivationSystem)
      activationSystemPreparer.prepareProxy(
                ActivationGroup.getSystem());
        logger.log(Level.FINE, "Prepared ActivationSystem: {0}",
            activationSystem);
  activationID = (ActivationID
      activationIdPreparer.prepareProxy(activationID);
        logger.log(Level.FINEST, "Prepared ActivationID: {0}",
            activationID);

        /**
   * Would like to get this entry sooner, but need to use
   * the prepared activationID.
   */
  exporter = (Exporter) config.getEntry(
                START_PACKAGE, "exporter", Exporter.class,
    new ActivationExporter(
        activationID,
        new BasicJeriExporter(
      TcpServerEndpoint.getInstance(0),
      new BasicILFactory(), false, true)),
    activationID);
  if (exporter == null) {
             throw new ConfigurationException(START_PACKAGE
       + ".exporter entry should not be null");
        }
        logger.log(Level.FINE, START_PACKAGE + ".exporter: {0}",
            exporter);
 
  // Export service
        ourStub = exporter.export(this);   
        logger.log(Level.FINEST, "Exported service proxy: {0}",
            ourStub);
    }

    // javadoc inherited from supertype
    public void destroyVM() throws RemoteException, ActivationException {
  logger.entering(SharedGroupImpl.class.getName(), "destroyVM");
  /*
   * Would like to synch access to activationSystem, but need
   * to avoid holding locks across remote invocations.
   */
        if (activationSystem != null) {
      activationSystem.unregisterGroup(
    ActivationGroup.currentGroupID());
                logger.finest("ActivationGroup unregistered.");
    /* Unregistering the group implicitly unregisters
     * all the objects associated with that group as well.
     */
      activationSystem = null;    
  }
        (new DestroyThread()).start();
  logger.exiting(SharedGroupImpl.class.getName(), "destroyVM");
    }

    /**
     * Private utility method which attempts to roll back from
     * from a failed initialization attempt.
     */
    private void cleanup() {
  logger.entering(SharedGroupImpl.class.getName(), "cleanup");
        /*
   * Caller decides whether or not to unregister this object.
   */
        if (exporter != null) {
            try {
          // Unexport object so that no new calls come in
          exporter.unexport(true);
                logger.finest("SharedGroupImpl unexported.");
      } catch (Exception e) {
                logger.log(Level.FINEST,
        "Problem unexporting SharedGroupImpl.", e);
      }
        }
   
  if (loginContext != null) {
      try {
    loginContext.logout();
                logger.finest("SharedGroupImpl logged-out.");
      } catch (Exception e) {
                logger.log(Level.FINEST,
        "Problem logging out for SharedGroupImpl.", e);
      }
  }
  logger.exiting(SharedGroupImpl.class.getName(), "cleanup");
    }

    /**
     * Termination thread code.  We do this in a separate thread to
     * allow the calling thread to return normally. This is not guaranteed
     * since it's still possible for the VM to exit before the calling
     * thread returns.
     */
    private class DestroyThread extends Thread {

        /** Create a non-daemon thread */
        public DestroyThread() {
            super("DestroyThread");
            /* override inheritance from RMI daemon thread */
            setDaemon(false);
        }

        public void run() {
            logger.entering(DestroyThread.class.getName(),
                "run");
            logger.finest("Calling System.exit() ...");

      /*
       * Forcefully destroy the VM, in case there are any lingering
       * threads.
       */
      System.exit(0);
        }
    }
    // inherit javadoc
    public Object getProxy() {
        logger.entering(SharedGroupImpl.class.getName(),
                "getProxy");
        logger.exiting(SharedGroupImpl.class.getName(),
                "getProxy", ourStub);
  return ourStub;
    }
   
    //////////////////////////////////////////
    // ProxyTrust Method
    //////////////////////////////////////////
    //inherit javadoc
    public TrustVerifier getProxyVerifier( ) {
        /* No verifier if the server isn't secure */
        if (!(ourStub instanceof RemoteMethodControl)) {
            throw new UnsupportedOperationException();
        } else {
            return new ProxyVerifier((SharedGroupBackEnd)ourStub);
        }
    }
}
TOP

Related Classes of com.sun.jini.start.SharedGroupImpl$DestroyThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.