Package hermes

Source Code of hermes.JAXBHermesLoader

/*
* Copyright 2003,2004 Colin Crist
*
* Licensed 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 hermes;

import hermes.browser.HermesBrowser;
import hermes.browser.dialog.SelectorImpl;
import hermes.config.ClasspathGroupConfig;
import hermes.config.ConnectionConfig;
import hermes.config.DestinationConfig;
import hermes.config.FactoryConfig;
import hermes.config.HermesConfig;
import hermes.config.NamingConfig;
import hermes.config.QuickFIXConfig;
import hermes.config.SessionConfig;
import hermes.config.WatchConfig;
import hermes.fix.quickfix.QuickFIXMessageCache;
import hermes.impl.ClassLoaderManager;
import hermes.impl.ConnectionFactoryManager;
import hermes.impl.ConnectionFactoryManagerImpl;
import hermes.impl.ConnectionManager;
import hermes.impl.ConnectionManagerFactory;
import hermes.impl.DefaultHermesImpl;
import hermes.impl.DestinationManager;
import hermes.impl.JNDIDestinationManager;
import hermes.impl.NullClassLoaderManager;
import hermes.impl.SessionManager;
import hermes.impl.SimpleClassLoaderManager;
import hermes.impl.jms.SimpleDestinationManager;
import hermes.impl.jms.ThreadLocalSessionManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jms.JMSException;
import javax.jms.QueueConnectionFactory;
import javax.jms.TopicConnectionFactory;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import org.apache.log4j.Logger;

/**
* @author colincrist@hermesjms.com
* @version $Id: JAXBHermesLoader.java,v 1.52 2007/02/18 19:01:42 colincrist Exp
*          $
*/
public class JAXBHermesLoader implements HermesLoader {
  private static final Logger log = Logger.getLogger(JAXBHermesLoader.class);
  private static final String FILE_NAME = "hermes-config.xml";
  private static final String DEFAULT_EXTENSION_LOADER = "hermes.ext.ExtensionFinderImpl";

  private URL url;
  private File file;
  private HermesConfig config;
  private JAXBElement<HermesConfig> element;
  private ClassLoaderManager classLoaderManager;
  private Hashtable properties;
  private final Set listeners = new HashSet();
  private final Map<String, FactoryConfig> factoryConfigById = new HashMap<String, FactoryConfig>();
  private boolean ignoreClasspathGroups;

  private Context context;
  private String extensionLoaderClass = DEFAULT_EXTENSION_LOADER;
  private final ThreadLocal<JAXBContext> contextTL = new ThreadLocal<JAXBContext>() {
    @Override
    protected JAXBContext initialValue() {
      try {
        return JAXBContext.newInstance("hermes.config");
      } catch (JAXBException e) {
        log.error(e.getMessage(), e);
        return null;
      }
    }
  };

  public JAXBHermesLoader() {

  }

  @Override
  public void setContext(Context context) {
    this.context = context;
  }

  @Override
  public void backup() throws HermesException {
    try {
      if (file != null) {
        copyFile(file.getAbsolutePath(), file.getAbsolutePath() + ".backup");
      }
    } catch (IOException e) {
      throw new HermesException(e);
    }
  }

  @Override
  public void restore() throws HermesException {
    try {
      if (file != null) {
        copyFile(file.getAbsolutePath() + ".backup", file.getAbsolutePath());
      }
    } catch (IOException e) {
      throw new HermesException(e);
    }
  }

  @Override
  public void save() throws HermesException {
    try {
      if (file != null) {
        OutputStream ostream = new FileOutputStream(file);
        Marshaller m = contextTL.get().createMarshaller();
        config.setLastEditedByHermesVersion(Hermes.VERSION);
        config.setLastEditedByUser(System.getProperty("user.name"));
        config.setLookAndFeel(UIManager.getLookAndFeel().getClass().getName());

        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        element.setValue(config);
        m.marshal(element, ostream);

        ostream.close();
      } else {
        throw new HermesException("No file to save configuration to (did you load from a URL?)");
      }
    } catch (FileNotFoundException e) {
      throw new HermesException(e);
    } catch (PropertyException e) {
      throw new HermesException(e);
    } catch (JAXBException e) {
      throw new HermesException(e);
    } catch (IOException e) {
      throw new HermesException(e);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see hermes.HermesLoader#doLoad()
   */

  @Override
  public void addDestinationConfig(Hermes hermes, DestinationConfig config) throws JMSException {
    if (factoryConfigById.containsKey(hermes.getId())) {
      FactoryConfig fConfig = factoryConfigById.get(hermes.getId());
      fConfig.getDestination().add(config);
      hermes.addDestinationConfig(config);
      notifyDestinationAdded(hermes, config);
    } else {
      throw new HermesException("No such session " + hermes.getId());
    }
  }

  @Override
  public void replaceDestinationConfigs(Hermes hermes, Collection dConfigs) throws JMSException {
    boolean keepDurableSubscriptions = true, keepDurableSubscriptionsDialogShown = false;

    // HJMS-139

    for (final Iterator iter = dConfigs.iterator(); iter.hasNext();) {
      final DestinationConfig dConfig = (DestinationConfig) iter.next();
      DestinationConfig oldConfig = null;

      try {
        if (dConfig.getDomain() == Domain.TOPIC.getId()) {
          oldConfig = hermes.getDestinationConfig(dConfig.getName(), Domain.TOPIC);
        } else {
          oldConfig = hermes.getDestinationConfig(dConfig.getName(), Domain.QUEUE);
        }
      } catch (Throwable t) {
        log.error(t.getMessage(), t);
      }

      if (oldConfig != null && oldConfig.getProperties() != null) {
        dConfig.setProperties(oldConfig.getProperties());
      }
    }

    // End HJMS-139

    if (factoryConfigById.containsKey(hermes.getId())) {
      final FactoryConfig fConfig = factoryConfigById.get(hermes.getId());

      for (final Iterator iter = fConfig.getDestination().iterator(); iter.hasNext();) {
        final DestinationConfig dConfig = (DestinationConfig) iter.next();

        if (dConfig.getDomain() == Domain.TOPIC.getId() && dConfig.isDurable()) {
          if (!keepDurableSubscriptionsDialogShown) {
            if (HermesBrowser.getBrowser() != null) {
              if (JOptionPane.showConfirmDialog(HermesBrowser.getBrowser(), "Do you want to keep configured durable subscriptions?", "Durable Subscriptions", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
                keepDurableSubscriptions = false;
              }
            }

            keepDurableSubscriptionsDialogShown = true;
          }

          if (!keepDurableSubscriptions) {
            iter.remove();
            notifyDestinationRemoved(hermes, dConfig);
          }
        } else {
          iter.remove();
          notifyDestinationRemoved(hermes, dConfig);
        }
      }

      for (final Iterator iter = dConfigs.iterator(); iter.hasNext();) {
        final DestinationConfig dConfig = (DestinationConfig) iter.next();

        fConfig.getDestination().add(dConfig);
        hermes.addDestinationConfig(dConfig);
        notifyDestinationAdded(hermes, dConfig);
      }
    } else {
      throw new HermesException("No such session " + hermes.getId());
    }
  }

  /**
   * Everything is in here to load up all the Hermes instances from JAXB, it
   * kinda sux really. Would be nice to have proper framework for this.
   */
  @Override
  public List<Hermes> load() throws HermesException {
    ArrayList<Hermes> rval = null;
    InputStream istream = null;
    String from;

    factoryConfigById.clear();

    if (properties == null) {
      throw new HermesException("No properties available");
    }

    try {
      if (file == null) {
        if (!properties.containsKey(Context.PROVIDER_URL)) {
          from = FILE_NAME;
        } else {
          from = (String) properties.get(Context.PROVIDER_URL);
        }

        log.debug("attempting to load from URL: " + from);

        try {
          istream = new URL(from).openStream();
        } catch (IOException ex) {
          log.info("failed to load configuration from " + from + ", attempting to load as a file...");
        }

        if (istream == null) {
          file = new File(from);

          log.debug("trying to load from file: " + file.getName());

          if (!file.exists()) {
            throw new NoConfigurationException();
          }

          istream = new FileInputStream(file);
        }

      } else {
        istream = new FileInputStream(file);
      }

      rval = new ArrayList<Hermes>();

      Unmarshaller u = contextTL.get().createUnmarshaller();

      element = u.unmarshal(new StreamSource(istream), HermesConfig.class);

      config = element.getValue();

      Hermes.ui.setConfig(config);

      if (config.getLastEditedByHermesVersion() == null) {
        //
        // First time Hermes1.7RC3 was run with this config

        config.setLastEditedByHermesVersion(Hermes.VERSION);
        config.setDisplayFactoryAdmin(true);
      }

      // This is for the 1.10 upgrade

      if (config.getQuickFIX() == null) {
        QuickFIXConfig quickFIXConfig = new QuickFIXConfig();

        quickFIXConfig.setCacheSize(1024);

        config.setQuickFIX(quickFIXConfig);
      }

      config.setSelectorImpl(SelectorImpl.JAMSEL.getClazz().getName());

      // This is for the 1.9 upgrdfe

      if (config.getAutoBrowseRefreshRate() == 0) {
        config.setAutoBrowseRefreshRate(10);
      }

      //
      // This is for the 1.8 upgrade

      if (config.getMaxColumnsInStatisticsTable() == 0) {
        config.setMaxColumnsInStatisticsTable(10);
      }

      //
      // This is for the 1.7 upgrade where we want to move the old global
      // classloader into a default ClassloaderGroup.

      if (config.getLoader() != null && config.getLoader().size() > 0) {
        ClasspathGroupConfig gConfig = new ClasspathGroupConfig();
        gConfig.setId(SimpleClassLoaderManager.DEFAULT_LOADER);
        gConfig.getLibrary().addAll(config.getLoader());

        config.getClasspathGroup().clear();
        config.getClasspathGroup().add(gConfig);
        config.getLoader().clear();
      }

      if (!ignoreClasspathGroups) {
        classLoaderManager = new SimpleClassLoaderManager(config.getClasspathGroup());
      } else {
        classLoaderManager = new NullClassLoaderManager();
      }

      SingletonManager.put(ClassLoaderManager.class, classLoaderManager);

      //
      // QuickFIX

      QuickFIXMessageCache cache = (QuickFIXMessageCache) SingletonManager.get(QuickFIXMessageCache.class);
      cache.setSize(config.getQuickFIX().getCacheSize());

      //
      // Deal with any renderers

      HermesBrowser.getRendererManager().setConfig(classLoaderManager.getDefaultClassLoader(), config);
      Hermes.ui.getThreadPool().setThreads(config.getMaxThreadPoolSize());

      // HermesBrowser.getThreadPool().setClassLoader(classLoader);

      if (config.getWatch() == null) {
        //
        // Maybe an upgrade from a pre-1.6 version, fill in what should
        // be there in the config.

        WatchConfig wConfig = new WatchConfig();

        wConfig.setShowAge(true);
        config.getWatch().add(wConfig);
      }

      for (Iterator iter = config.getFactory().iterator(); iter.hasNext();) {
        final FactoryConfig factoryConfig = (FactoryConfig) iter.next();

        /*
         * If for some reason the XML has no connection or sesssion then
         * clean up the XML.
         */

        if (factoryConfig.getConnection().size() == 0) {
          log.debug("cleaning up FactoryConfig with no connections");
          iter.remove();
          continue;
        }

        ConnectionConfig firstConnection = factoryConfig.getConnection().get(0);

        if (firstConnection.getSession().size() == 0) {
          log.debug("cleaning up FactoryConfig with no sessions");
          iter.remove();
          continue;
        }

        SessionConfig firstSession = firstConnection.getSession().get(0);

        if (firstSession.getId() == null) {
          log.debug("cleaning up FactoryConfig with a null session");
          iter.remove();
          continue;
        }

        try {

          Hermes hermes = createHermes(factoryConfig);

          rval.add(hermes);

          notifyHermesAdded(hermes);

          for (Iterator diter = hermes.getDestinations(); diter.hasNext();) {
            DestinationConfig destinationConfig = (DestinationConfig) diter.next();

            boolean isQueue = hermes.getConnectionFactory() instanceof QueueConnectionFactory;
            boolean isTopic = hermes.getConnectionFactory() instanceof TopicConnectionFactory;

            if (destinationConfig.getDomain() == 0 && HermesBrowser.getBrowser() != null) {
              if (isQueue && isTopic) {
                Object options[] = { "Queue", "Topic" };

                int n = JOptionPane.showOptionDialog(HermesBrowser.getBrowser(), "This XML is from an older version of Hermes and it is unclear which domain the destination\n"
                    + destinationConfig.getName() + " for session " + hermes.getId() + " is in. Please choose whether queue or topic domain", "Select domain",
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);

                if (n == JOptionPane.YES_OPTION) {
                  isQueue = true;
                  isTopic = false;

                  log.info(destinationConfig.getName() + " is now in the queue domain");
                } else {
                  isQueue = false;
                  isTopic = true;

                  log.info(destinationConfig.getName() + " is now in the topic domain");
                }
              }

              if (isQueue) {
                destinationConfig.setDomain(Domain.QUEUE.getId());
              } else if (isTopic) {
                destinationConfig.setDomain(Domain.TOPIC.getId());
              }
            }

            notifyDestinationAdded(hermes, destinationConfig);
          }
        }

        catch (Throwable t) {
          log.error("unable to create Hermes instance " + firstSession.getId() + ": " + t.getMessage(), t);
        }
      }

      return rval;

    } catch (Exception ex) {
      log.error(ex.getMessage(), ex);

      HermesBrowser.getBrowser().showErrorDialog("Unable to load configuration", ex);
      throw new HermesException(ex);
    }
  }

  @Override
  public Hermes createHermes(FactoryConfig factoryConfig) throws JAXBException, IOException, JMSException, NamingException, InstantiationException, ClassNotFoundException, IllegalAccessException,
      InvocationTargetException, NoSuchMethodException {
    Hermes hermes = null;
    ConnectionFactoryManager connectionFactoryManager = null;
    JNDIConnectionFactory jndiFactory = null;

    if (factoryConfig.getExtension() == null) {
      factoryConfig.setExtension(HermesBrowser.getConfigDAO().createDefaultProviderExtConfig(factoryConfig.getProvider().getClassName()));
    }

    ClassLoader classLoader = getClass().getClassLoader();

    if (factoryConfig.getClasspathId() == null) {
      factoryConfig.setClasspathId(SimpleClassLoaderManager.DEFAULT_LOADER);
    }

    classLoader = classLoaderManager.createClassLoader(factoryConfig.getClasspathId(), factoryConfig.getExtension());
    Thread.currentThread().setContextClassLoader(classLoader);

    connectionFactoryManager = new ConnectionFactoryManagerImpl(classLoaderManager, factoryConfig);

    //
    // You can now get the factory from the manager.

    if (factoryConfig.getProvider().getClassName().equals(JNDIConnectionFactory.class.getName()) || factoryConfig.getProvider().getClassName().equals(JNDIQueueConnectionFactory.class.getName())
        || factoryConfig.getProvider().getClassName().equals(JNDITopicConnectionFactory.class.getName())) {

      jndiFactory = (JNDIConnectionFactory) connectionFactoryManager.getConnectionFactory();
      jndiFactory._setDelegateClassLoader(classLoader);
    }

    for (Iterator iter2 = factoryConfig.getDestination().iterator(); iter2.hasNext();) {
      DestinationConfig destinationConfig = (DestinationConfig) iter2.next();

      if (destinationConfig.isDurable() && destinationConfig.getClientID() == null) {
        log.warn("removing durable subscription to " + destinationConfig.getName() + "with a null clientID");
        iter2.remove();
      } else {
        connectionFactoryManager.addDestinationConfig(destinationConfig);
      }
    }

    if (factoryConfig.getConnection().size() > 0) {
      ConnectionConfig connectionConfig = factoryConfig.getConnection().get(0);
      ConnectionManager connectionManager = null;

      if (connectionConfig.isConnectionPerThread()) {
        connectionManager = ConnectionManagerFactory.create(ConnectionManager.Policy.CONNECTION_PER_THREAD);
      } else {
        connectionManager = ConnectionManagerFactory.create(ConnectionManager.Policy.SHARED_CONNECTION);
      }

      connectionManager.setClientID(connectionConfig.getClientID());
      connectionManager.setUsername(connectionConfig.getUsername());
      connectionManager.setPassword(connectionConfig.getPassword());

      if (connectionConfig.getSession().size() > 0) {
        SessionManager sessionManager;
        DestinationManager destinationManager;
        SessionConfig sessionConfig = connectionConfig.getSession().get(0);

        if (jndiFactory != null) {
          jndiFactory._setDelegateClassLoader(classLoader);

          destinationManager = new JNDIDestinationManager(jndiFactory._getProperties(), true);
          sessionManager = new ThreadLocalSessionManager(sessionConfig, destinationManager);
        } else {
          destinationManager = new SimpleDestinationManager();
          sessionManager = new ThreadLocalSessionManager(sessionConfig, destinationManager);
        }

        log.debug("SESSION IS " + sessionConfig.getId());

        if (sessionConfig.getReconnects() != null) {
          sessionManager.setReconnects(sessionConfig.getReconnects().intValue());
        }

        classLoaderManager.putClassLoaderByHermes(sessionConfig.getId(), classLoader);
        factoryConfigById.put(sessionConfig.getId(), factoryConfig);

        sessionManager.setTransacted(sessionConfig.isTransacted());
        sessionManager.setId(sessionConfig.getId());
        sessionManager.setFactoryConfig(factoryConfig);
        sessionManager.setAudit(sessionConfig.isAudit());

        sessionManager.setParent(connectionManager);
        connectionManager.setParent(connectionFactoryManager);

        if (config.getAuditDirectory() != null) {
          sessionManager.setAuditDirectory(config.getAuditDirectory());
        } else if (sessionConfig.getAuditDirectory() != null) {
          sessionManager.setAuditDirectory(sessionConfig.getAuditDirectory());
        }

        connectionManager.addChild(sessionManager);

        hermes = new DefaultHermesImpl(factoryConfig.getExtension(), sessionManager, classLoader);

        connectionFactoryManager.addChild(connectionManager);
        connectionManager.setHermes(hermes);
      }

    }
    return hermes;
  }

  /*
   * (non-Javadoc)
   *
   * @see hermes.HermesLoader#getConfig()
   */

  @Override
  public HermesConfig getConfig() throws HermesException {
    return config;
  }

  private static void copyFile(String src, String dest) throws IOException {
    File destFile = new File(dest);

    if (destFile.exists()) {
      destFile.delete();
    }

    FileChannel srcChannel = new FileInputStream(src).getChannel();
    FileChannel dstChannel = new FileOutputStream(dest).getChannel();

    dstChannel.transferFrom(srcChannel, 0, srcChannel.size());

    srcChannel.close();
    dstChannel.close();
  }

  /*
   * (non-Javadoc)
   *
   * @see hermes.HermesLoader#setProperties(java.util.Hashtable)
   */
  @Override
  public void setProperties(Hashtable map) {
    this.properties = map;

  }

  @Override
  public Iterator getConfigurationListeners() {
    return listeners.iterator();
  }

  @Override
  public void addConfigurationListener(HermesConfigurationListener listener) {

    listeners.add(listener);

    //
    // Give it its initial state..

    try {
      for (NamingEnumeration e = context.listBindings(""); e.hasMore();) {
        Binding binding = (Binding) e.next();

        try {
          if (context.lookup(binding.getName()) instanceof Hermes) {
            Hermes hermes = (Hermes) context.lookup(binding.getName());

            listener.onHermesAdded(hermes);

            for (Iterator diter = hermes.getDestinations(); diter.hasNext();) {
              DestinationConfig destinationConfig = (DestinationConfig) diter.next();

              listener.onDestinationAdded(hermes, destinationConfig);
            }
          }
        } catch (NamingException ex) {
          // NOP
        }
      }

      for (Iterator namingIter = config.getNaming().iterator(); namingIter.hasNext();) {
        NamingConfig namingConfig = (NamingConfig) namingIter.next();

        listener.onNamingAdded(namingConfig);
      }
    } catch (NamingException e) {
      log.error(e.getMessage(), e);
    }
  }

  public void removeConfigurationListener(HermesConfigurationListener listener) {
    listeners.remove(listener);
  }

  public void notifyNamingAdded(NamingConfig namingConfig) {
    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
      HermesConfigurationListener listener = (HermesConfigurationListener) iter.next();
      listener.onNamingAdded(namingConfig);
    }
  }

  @Override
  public void notifyNamingRemoved(NamingConfig namingConfig) {
    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
      HermesConfigurationListener listener = (HermesConfigurationListener) iter.next();
      listener.onNamingRemoved(namingConfig);
    }
  }

  public void notifyHermesAdded(Hermes hermes) {
    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
      HermesConfigurationListener listener = (HermesConfigurationListener) iter.next();
      listener.onHermesAdded(hermes);
    }
  }

  @Override
  public void notifyHermesRemoved(Hermes hermes) {
    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
      HermesConfigurationListener listener = (HermesConfigurationListener) iter.next();
      listener.onHermesRemoved(hermes);
    }
  }

  public void notifyDestinationAdded(Hermes hermes, DestinationConfig destinationConfig) {
    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
      HermesConfigurationListener listener = (HermesConfigurationListener) iter.next();
      listener.onDestinationAdded(hermes, destinationConfig);
    }
  }

  public void notifyDestinationRemoved(Hermes hermes, DestinationConfig destinationConfig) {
    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
      HermesConfigurationListener listener = (HermesConfigurationListener) iter.next();
      listener.onDestinationRemoved(hermes, destinationConfig);
    }
  }

  /**
   * @return Returns the context.
   */
  @Override
  public Context getContext() {
    return context;
  }

  /**
   * @param extensionLoaderClass
   *            The extensionLoaderClass to set.
   */
  @Override
  public void setExtensionLoaderClass(String extensionLoader) {
    this.extensionLoaderClass = extensionLoader;
  }

  @Override
  public ClassLoaderManager getClassLoaderManager() {
    return classLoaderManager;
  }

  public boolean isIgnoreClasspathGroups() {
    return ignoreClasspathGroups;
  }

  @Override
  public void setIgnoreClasspathGroups(boolean ignoreClasspathGroups) {
    this.ignoreClasspathGroups = ignoreClasspathGroups;
  }
}
TOP

Related Classes of hermes.JAXBHermesLoader

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.