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

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

/*
 * TeleStax, Open Source Cloud Communications
 * Copyright 2011-2016, TeleStax Inc. and individual contributors
 * by the @authors tag.
 *
 * This program is free software: you can redistribute it and/or modify
 * under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see 
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 *   JBoss, Home of Professional Open Source
 *   Copyright 2007-2011, 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 java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
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 */ @SuppressWarnings("all") //3rd party lib 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 * * @throws 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 * * @throws 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 * * @throws 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(); } } } @SuppressWarnings("all") //3rd party lib 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 = System.getProperty("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; GetPropertyAction(String s) { theProp = s; } GetPropertyAction(String s, String s1) { theProp = s; defaultVal = s1; } @Override public String run() { String s = System.getProperty(theProp); return s != null ? s : defaultVal; } } @SuppressWarnings("all") //3rd party lib class StackInfo { Stack stack; Class stackClass; String stackClassName; @Override public String toString() { return (new StringBuilder().append("stack[className=").append(stackClassName).append(",").append(stack).append("]") .toString()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy