Package fr.dyade.aaa.jndi2.impl

Source Code of fr.dyade.aaa.jndi2.impl.ContextManager

/*
* JORAM: Java(TM) Open Reliable Asynchronous Messaging
* Copyright (C) 2001 - 2008 ScalAgent Distributed Technologies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA.
*
* Initial developer(s): Sofiane Chibani
* Contributor(s): David Feliot, Nicolas Tachker
*/
package fr.dyade.aaa.jndi2.impl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Enumeration;
import java.util.Vector;

import javax.naming.CompositeName;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.NotContextException;

import org.objectweb.util.monolog.api.BasicLevel;

import fr.dyade.aaa.util.NullTransaction;
import fr.dyade.aaa.util.Transaction;
import fr.dyade.aaa.util.management.MXWrapper;

public class ContextManager
    implements java.io.Serializable {

  /**
   *
   */
  private static final long serialVersionUID = 1L;

  private ContextTable contextIdTable;

  private ContextTable contextNameTable;

  private NamingContextId rootContextId;

  private StorageManager storageManager;

  public ContextManager(Transaction transaction,
                        Object serverId,
                        Object rootOwnerId) {   
    if (transaction instanceof NullTransaction) {
      contextNameTable = new SimpleContextTable();
      contextIdTable = new SimpleContextTable();
    } else {
      contextNameTable = new ContextCache();
      contextIdTable = new ContextCache();
    }  
    rootContextId = new NamingContextId(
      rootOwnerId, 0);
    storageManager = new StorageManager(
      transaction, serverId);
  }

  public void initialize() throws Exception {
    storageManager.initialize();  

    Enumeration names = storageManager.getContextNames();
    while (names.hasMoreElements()) {
      CompositeName name = (CompositeName) names.nextElement();
      // register MBean
      registerMBean(getNamingContextFromName(name), name);
    }
  }

  private void put(NamingContext nc) {
    contextIdTable.put(nc.getId(), nc);
  }

  private void put(CompositeName name, NamingContext nc) {
    contextNameTable.put(name, nc);
  }

  public NamingContext getNamingContext(NamingContextId ncid) throws NamingException {
    return getNamingContext(ncid, true);
  }

  public NamingContext getNamingContext(
    NamingContextId ncid,
    boolean cache)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.getNamingContext(" +
                       ncid + ',' + cache + ')');
    NamingContext nc = contextIdTable.get(ncid);
    if (nc != null) return nc ;

    nc = storageManager.loadNamingContext(ncid);
    if (cache && nc != null) put(nc);
    return nc;
  }

  private NamingContext getNamingContextFromName(CompositeName name)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.getNamingContextFromName(" + name + ')');

    // 1- Try to get the context directly from the cache
    NamingContext nc = contextNameTable.get(name);
    if (nc != null) return nc;

    // 2- Try to get the context id from the index of
    // the storage manager.
    NamingContextId ncid = storageManager.getIdFromName(name);
    if (ncid != null) {
      // 3- Get the naming context
      nc = getNamingContext(ncid);
      if (nc == null) {
        // The context no longer exists, thow an Exception. The JNDI server
        // is in an incoherent state, may be we should reinitialized it.
        throw new NamingException("Missing context: name=" + name + ", id=" + ncid);
      }
      put(name, nc);
      return nc;
    }
    return null;
  }
 
  public NamingContext getNamingContext(CompositeName name)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(
        BasicLevel.DEBUG,
        "ContextManager.getNamingContext(" +
        name + ')');

    NamingContext nc = getNamingContextFromName(name);
    if (nc != null) return nc;

    // Go upward the naming path in order to find out which name is missing.
    CompositeName parentName = name;
    NamingContext parentNc = null;
    int unresolvedIndex = 0;
    for (int i = 0; i < name.size(); i++) {
      parentName = (CompositeName)parentName.clone();
      parentName.remove(parentName.size() - 1);
      parentNc = getNamingContextFromName(parentName);
      if (parentNc != null) {
        unresolvedIndex = name.size() - 1 - i;
        break;
      }
    }

    if (parentNc == null) {
      // Shows that the root context is missing
      throw new MissingContextException(
        rootContextId, name);
    }

    // Find out why the naming context has not been
    // found.
    String unresolvedName = name.get(unresolvedIndex);
    Record record = parentNc.getRecord(unresolvedName);
    if (record == null) {
      NameNotFoundException nnfe =
        new NameNotFoundException();
      CompositeName resolvedName = new CompositeName();
      for (int j = 0; j < unresolvedIndex; j++) {
        resolvedName.add(name.get(j));
      }
      nnfe.setResolvedName(resolvedName);
      throw new MissingRecordException(
        parentNc.getId(),
        parentNc.getOwnerId(),
        nnfe);
    } else if (record instanceof ContextRecord) {
      ContextRecord ctxRecord = (ContextRecord)record;
      // The naming context is missing.
      // (we would have found it during the upward search)     
      throw new MissingContextException(
        ctxRecord.getId(), name);
    } else {
      throw new NotContextException();
    }
  }

  public void delete(NamingContextId ncid,
                     CompositeName name)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.delete(" +
                       ncid + ',' + name + ')');
    contextIdTable.remove(ncid);
    contextNameTable.remove(name);
    storageManager.delete(ncid, name);
   
    // unregister MBean
    unregisterMBean(name);
  }

  public NamingContextInfo[] copyNamingContexts(Object serverId)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.getNamingContexts(" +
                       serverId + ')');   
    Vector contexts = new Vector();
    Enumeration nameEnum = storageManager.getContextNames();
    Enumeration idEnum = storageManager.getContextIds();
    while (idEnum.hasMoreElements()) {
      NamingContextId ncid =
        (NamingContextId)idEnum.nextElement();
      CompositeName name =
        (CompositeName)nameEnum.nextElement();
      NamingContext nc = getNamingContext(ncid, false);     
      if (nc.getOwnerId().equals(serverId)) {
        NamingContext ncCopy = (NamingContext)nc.clone();
        contexts.addElement(
          new NamingContextInfo(ncCopy, name));
      }
    }
   
    NamingContextInfo[] res =
      new NamingContextInfo[contexts.size()];
    contexts.copyInto(res);
    return res;
  }

  public NamingContext newNamingContext(Object ownerId,
                                        NamingContextId ncid,
                                        CompositeName name)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.newNamingContext(" +
                       ownerId + ',' + ncid + ',' + name + ')');
   
    NamingContext nc =
      storageManager.newNamingContext(
        ownerId, ncid, name);
    put(nc);
    put(name, nc);

    // register MBean
    registerMBean(nc, name);

    return nc;
  }

  public void addNamingContext(NamingContextInfo ncInfo)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.addNamingContext(" +
                       ncInfo + ')');
    NamingContext nc = ncInfo.getNamingContext();
    CompositeName name = ncInfo.getCompositeName();
    storageManager.addNamingContext(
      nc, name);
    put(nc);
    put(name, nc);
  }
 
  public NamingContext getRootNamingContext()
    throws NamingException {
    return getNamingContext(rootContextId);
  }

  public void storeNamingContext(NamingContext nc)
    throws NamingException {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "ContextManager.storeNamingContext(" +
                       nc + ')');
    storageManager.storeNamingContext(nc);
  }

  public NamingContextInfo[] changeOwner(
      CompositeName cn,
      Object formerOwnerId,
      Object newOwnerId) throws NamingException {
    Vector updatedContexts = new Vector();
    Enumeration idEnum = storageManager.getContextIds();
    Enumeration nameEnum = storageManager.getContextNames();
    while (idEnum.hasMoreElements()) {
      NamingContextId ncid =
        (NamingContextId)idEnum.nextElement();
      CompositeName name =
        (CompositeName)nameEnum.nextElement();
      NamingContext nc = getNamingContext(ncid, false);     
      if (nc.getOwnerId().equals(formerOwnerId) && (name.equals(cn) || cn == null)) {
        nc.setOwnerId(newOwnerId);
        storageManager.storeNamingContext(nc);
        updatedContexts.addElement(
          new NamingContextInfo(nc, name));
        reloadMBean(nc);
      }
    }
    NamingContextInfo[] res =
      new NamingContextInfo[updatedContexts.size()];
    updatedContexts.copyInto(res);
    return res;
  }

  public void resetNamingContext(NamingContext context)
  throws NamingException {
    storageManager.storeNamingContext(context);
    reloadMBean(context);
  }
 
  private void registerMBean(NamingContext context, CompositeName cn) {
    try {
        MXWrapper.registerMBean(context, "JNDI", "nc=/"+cn);
    } catch (Exception exc) {
      Trace.logger.log(BasicLevel.WARN, context + " jmx failed", exc);
    }
  }
 
  private void unregisterMBean(CompositeName cn) {
    try {
      MXWrapper.unregisterMBean("JNDI", "nc=/"+cn);
    } catch (Exception exc) {
      Trace.logger.log(BasicLevel.WARN, "jmx failed", exc);
    }
  }
 
  private void reloadMBean(NamingContext context) {
      CompositeName cn = context.getContextName();
      if (cn.size() > 0) {
        unregisterMBean(cn);
        registerMBean(context, cn);
      }
  }
 
  public void writeBag(ObjectOutputStream out)
    throws IOException {
    out.writeObject(contextIdTable);
    out.writeObject(contextNameTable);
    storageManager.writeBag(out);
  }

  public void readBag(ObjectInputStream in)
    throws IOException, ClassNotFoundException {
    contextIdTable = (ContextTable)in.readObject();
    contextNameTable = (ContextTable)in.readObject();
    storageManager.readBag(in);
  }
}
TOP

Related Classes of fr.dyade.aaa.jndi2.impl.ContextManager

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.