All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdiameter.api.StackManager Maven / Gradle / Ivy

There is a newer version: 1.7.1-123
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2006, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This 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 (at your option) any later version.
 *
 * This software 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 software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jdiameter.api;

import java.io.PrintWriter;
import static java.security.AccessController.doPrivileged;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 

The basic service for managing a set of Diameter stacks.
* *

As part of its initialization, the DriverManager class will * attempt to load the stacks classes referenced in the "diameter.drivers" * system property. This allows a user to customize the Diameter Drivers * used by their applications. For example in your * ~/.hotjava/properties file you might specify: *

 * diameter.drivers=foo.bah.Stack:wombat.diameter.Stack
 * 
* * A program can also explicitly load Diameter stacks at any time. For * example, the my.diameter.Stack is loaded with the following statement: *
 * Class.forName("my.diameter.Stack");
 * 
* *

When the method getSession is called, * the StackManager will attempt to * locate a suitable stack from amongst those loaded at * initialization and those loaded explicitly using the same classloader * as the current applet or application. * * @author [email protected] * @version 1.5.1 Final */ public final class StackManager { private static final Object logSync = new Object(); private static List stacks = new CopyOnWriteArrayList(); private static PrintWriter logWriter = null; private static boolean initialized = false; static void initialize() { if (initialized) return; initialized = true; loadInitialStacks(); println("Diameter StackManager initialized"); } private StackManager() { } /** * Retrieves the log writer. * * The getLogWriter and setLogWriter * methods should be used instead * of the get/setlogStream methods, which are deprecated. * @return a java.io.PrintWriter object * @see #setLogWriter */ public static PrintWriter getLogWriter() { synchronized (logSync) { return logWriter; } } /** * Sets the logging/tracing PrintWriter object * that is used by the StackManager and all drivers. *

* There is a minor versioning problem created by the introduction * of the method setLogWriter. The * method setLogWriter cannot create a PrintStream object * that will be returned by getLogStream * * @param out the new logging/tracing PrintStream object; * null to disable logging and tracing * @throws SecurityException * if a security manager exists and its * checkPermission method denies * setting the log writer */ public static void setLogWriter(java.io.PrintWriter out) { synchronized (logSync) { logWriter = out; } } /** * Attempts to locate a stack. * The StackManager attempts to select an appropriate stack from * the set of registered Diameter stacks. * @param className class name of stack * @return stack instance * @exception InternalException if a manager has internal error */ public static synchronized Stack getStack(String className) throws InternalException { println(new StringBuilder().append("StackManager.getStack(\"").append(className).append("\")").toString()); if (!initialized) { initialize(); } // Gets the classloader of the code that called this method, may be null. ClassLoader callerCL = ClassLoader.getSystemClassLoader(); // Walk through the loaded stacks attempting to locate someone who understands the given URL. for (StackInfo di : stacks) { // If the caller does not have permission to load the stack then skip it. if (getCallerClass(callerCL, di.stackClassName) != di.stackClass) { println(new StringBuilder().append(" skipping: ").append(di).toString()); continue; } println(new StringBuilder().append(" trying ").append(di).toString()); if (di.stackClassName.equals(className)) { // Success! println("geStack returning " + di); return (di.stack); } } println("getStack: no suitable stack"); throw new InternalException("No suitable stack"); } /** * Registers the given stack with the ScoketManager. * A newly-loaded stack class should call * the method registerStack to make itself * known to the StackManager. * * @param stack the new Diameter Stack that is to be registered with the * StackManager * @exception InternalException if a manager has internal error */ public static synchronized void registerStack(Stack stack) throws InternalException { if (!initialized) { initialize(); } StackInfo stackInfo = new StackInfo(); stackInfo.stack = stack; stackInfo.stackClass = stack.getClass(); stackInfo.stackClassName = stackInfo.stackClass.getName(); stacks.add(stackInfo); println(new StringBuilder().append("registerStack: ").append(stackInfo).toString()); } /** * Drops a driver from the DiameterManager's list. Applets can only * deregister stacks from their own classloaders. * * @param stack the Diameter stack to drop * @exception InternalException if a manager has internal error */ public static synchronized void deregisterStack(Stack stack) throws InternalException { // Gets the classloader of the code that called this method, may be null. ClassLoader callerCL = ClassLoader.getSystemClassLoader(); println(new StringBuilder().append("StackManager.deregisterStack: ").append(stack).toString()); // Walk through the loaded stacks. int i; StackInfo stackInfo = null; for (i = 0; i < stacks.size(); i++) { stackInfo = stacks.get(i); if (stackInfo.stack == stack) break; } // If we can't find the stack just return. if (i >= stacks.size()) { println(" couldn't find stack to unload"); return; } // If the caller does not have permission to load the stack then throw a security exception. if (stackInfo == null || getCallerClass(callerCL, stackInfo.stackClassName) != stackInfo.stackClass) { throw new SecurityException(); } // Remove the stack. Other entries in stacks get shuffled down. stacks.remove(i); } /** * Retrieves an Enumeration with all of the currently loaded Diameter stacks * to which the current caller has access. * *

Note: The classname of a stack can be found using * d.getClass().getName() * * @return the list of Diameter stacks loaded by the caller's class loader */ public static synchronized Enumeration getStacks() { List result = new CopyOnWriteArrayList(); if (!initialized) { initialize(); } // Gets the classloader of the code that called this method, may be null. ClassLoader callerCL = ClassLoader.getSystemClassLoader(); // Walk through the loaded stacks. for (StackInfo di : stacks) { // If the caller does not have permission to load the stack then skip it. if (getCallerClass(callerCL, di.stackClassName) != di.stackClass) { println(new StringBuilder().append(" skipping: ").append(di).toString()); continue; } result.add(di.stack); } return Collections.enumeration(result); } public static void println(String message) { synchronized (logSync) { if (logWriter != null) { logWriter.println(message); // automatic flushing is never enabled, so we must do it ourselves logWriter.flush(); } } } private static Class getCallerClass(ClassLoader callerClassLoader, String stackClassName) { Class callerC; try { callerC = Class.forName(stackClassName, true, callerClassLoader); } catch (Exception ex) { callerC = null; } return callerC; } private static void loadInitialStacks() { String stacks; try { stacks = doPrivileged( new GetPropertyAction("diameter.stacks") ); } catch (Exception ex) { stacks = null; } println(new StringBuilder().append("StackManager.initialize: diameter.stacks = ").append(stacks).toString()); if (stacks == null) return; while (stacks.length() != 0) { int x = stacks.indexOf(':'); String stack; if (x < 0) { stack = stacks; stacks = ""; } else { stack = stacks.substring(0, x); stacks = stacks.substring(x + 1); } if (stack.length() == 0) continue; try { println(new StringBuilder().append("StackManager.Initialize: loading ").append(stack).toString()); Class.forName(stack, true, ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println(new StringBuilder().append("StackManager.Initialize: load failed: ").append(ex).toString()); } } } } class GetPropertyAction implements PrivilegedAction { private String theProp; private String defaultVal; public GetPropertyAction(String s) { theProp = s; } public GetPropertyAction(String s, String s1) { theProp = s; defaultVal = s1; } public String run() { String s = System.getProperty(theProp); return s != null ? s : defaultVal; } } class StackInfo { Stack stack; Class stackClass; String stackClassName; public String toString() { return (new StringBuilder().append("stack[className=").append(stackClassName).append(","). append(stack).append("]").toString()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy