User: mulder  
  Date: 00/09/12 19:06:02

  Added:       src/main/org/jboss/dependencies DependencyManager.java
  Log:
  Add handling of MBean dependencies to startup sequence.
  
  Revision  Changes    Path
  1.1                  jboss/src/main/org/jboss/dependencies/DependencyManager.java
  
  Index: DependencyManager.java
  ===================================================================
  package org.jboss.dependencies;
  
  import java.io.IOException;
  import java.io.StringReader;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  import javax.management.MBeanServer;
  import javax.management.ObjectName;
  import javax.management.ReflectionException;
  import org.xml.sax.AttributeList;
  import org.xml.sax.HandlerBase;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import com.sun.xml.parser.Parser;
  import com.sun.xml.parser.Resolver;
  
  public class DependencyManager {
      private final static boolean DEBUG=false;
      private HashMap dependencies;
      private HashSet loadedBeans;
      private HashMap remainingBeans;
      private HashSet pendingBeans;
      private MBeanServer server;
  
      public DependencyManager() {
          dependencies = new HashMap();
          loadedBeans = new HashSet();
          remainingBeans = new HashMap();
          pendingBeans = new HashSet();
      }
  
      public void loadXML(String source) {
          dependencies.clear();
          Parser parser = new Parser();
          try {
              parser.setDocumentHandler(new SAXHandler());
              InputSource input = new InputSource(new StringReader(source));
              parser.parse(input);
          } catch(IOException e) {
              e.printStackTrace();
          } catch(SAXException e) {
              e.printStackTrace();
          }
      }
  
      public void startMBeans(MBeanServer server) {
          this.server = server;
          loadedBeans.clear();
          remainingBeans.clear();
          pendingBeans.clear();
          Iterator it = server.queryNames(null, null).iterator();
          while(it.hasNext()) {
              ObjectName name = (ObjectName)it.next();
              String service = getService(name);
              if(service == null)
                  continue;
              Set set = (Set)remainingBeans.get(service);
              if(set == null)
                  set = new HashSet();
              set.add(name);
              remainingBeans.put(service, set);
          }
          it = ((Map)remainingBeans.clone()).keySet().iterator();
          while(it.hasNext()) {
              String next = (String)it.next();
              if(!processMBean(next)) {
                  System.out.println("Unable to load service '"+next+"'");
              }
          }
          System.out.println(loadedBeans.size()+" services loaded.");
          loadedBeans.clear();
          dependencies.clear();
      }
  
      private boolean processMBean(String target) {
          if(pendingBeans.contains(target))
              throw new RuntimeException("Circular dependencies!");
          if(loadedBeans.contains(target))
              return true;
          if(DEBUG) System.out.println("Processing service '"+target+"'");
          pendingBeans.add(target);
          Set set = (Set)dependencies.get(target);
          if(set == null) {
              return loadMBean(target);
          } else {
              Iterator it = set.iterator();
              while(it.hasNext()) {
                  Dependency dep = (Dependency)it.next();
                  if(DEBUG) System.out.println("  Service '"+target+"' depends on 
'"+dep.name+"'");
                  if(!loadedBeans.contains(dep.name)) {
                      boolean result = processMBean(dep.name);
                      if(!result && dep.required)
                          return false;
                  }
              }
              return loadMBean(target);
          }
      }
  
      private boolean loadMBean(String target) {
          boolean loaded = false;
          Set set = (Set)remainingBeans.get(target);
          if(set != null) {
              if(DEBUG) System.out.println("Starting service '"+target+"'");
              Iterator it = set.iterator();
              while(it.hasNext()) {
                  ObjectName name = (ObjectName)it.next();
                  if(DEBUG) System.out.println("Starting instance 
'"+name.getCanonicalName()+"'");
                  try {
                      server.invoke(name, "start", new Object[0], new String[0]);
                      loaded = true;
                  } catch(ReflectionException e) {
                      if(e.getTargetException() instanceof NoSuchMethodException) {
                          loaded = true;  // This bean doesn't have a start!
                      } else {
                          System.out.println("Error starting service 
'"+name.getCanonicalName()+"': "+e.getTargetException());
                          loaded = false;
                          break;
                      }
                  } catch(Throwable t) {
                      System.out.println("Error starting service 
'"+name.getCanonicalName()+"': "+t);
                      loaded = false;
                      break;
                  }
              }
              remainingBeans.remove(target);
              dependencies.remove(target);
          }
          loadedBeans.add(target);
          pendingBeans.remove(target);
          return loaded;
      }
  
      private String getService(ObjectName oName) {
          String name = oName.getCanonicalName();
          int pos = name.indexOf("service=");
          if(pos < 0)
              return null;
          int test, end = name.length();
          test = name.indexOf(',', pos+8);
          if(test > -1 && test < end)
              end = test;
          test = name.indexOf(';', pos+8);
          if(test > -1 && test < end)
              end = test;
          return name.substring(pos+8, end);
      }
  
      public void dump() {
          Iterator it = dependencies.keySet().iterator();
          while(it.hasNext()) {
              String key = (String)it.next();
              Iterator child = ((HashSet)dependencies.get(key)).iterator();
              while(child.hasNext()) {
                  Dependency dep = (Dependency)child.next();
                  System.out.println(key+" depends on "+dep.name+(dep.required ? " 
REQUIRED" : ""));
              }
          }
      }
  
      public static void main(String args[]) {
          StringBuffer total = new StringBuffer();
          try{
              java.io.BufferedReader reader = new java.io.BufferedReader(new 
java.io.FileReader(new java.io.File(args[0])));
              String line;
              while((line = reader.readLine()) != null)
                  total.append(line).append('\n');
              DependencyManager dm = new DependencyManager();
              dm.loadXML(total.toString());
              dm.dump();
          } catch(IOException e) {e.printStackTrace();}
      }
  
      private class SAXHandler extends HandlerBase {
          private String currentService;
          public void endElement(String name) throws SAXException {
              if(name.equals("service"))
                  currentService = null;
          }
          public void startElement(String name, AttributeList atts) throws 
SAXException {
              if(name.equals("service")) {
                  currentService = atts.getValue("name");
                  dependencies.put(currentService, new HashSet());
              } else if(name.equals("dependency")) {
                  HashSet set = (HashSet)dependencies.get(currentService);
                  set.add(new Dependency(atts.getValue("service"), 
atts.getValue("required")));
              }
          }
      }
  }
  
  class Dependency {
      public String name;
      public boolean required;
  
      public Dependency(String name, String required) {
          this.name = name;
          this.required = new Boolean(required).booleanValue();
      }
  }
  
  
  

Reply via email to