Package org.apache.ws.util.jndi

Source Code of org.apache.ws.util.jndi.XmlBeanJndiUtils

/*=============================================================================*
*  Copyright 2004 The Apache Software Foundation
*
*  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 org.apache.ws.util.jndi;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.resource.JndiConstants;
import org.apache.ws.util.jndi.tools.ConfigContext;
import org.apache.ws.util.jndi.tools.Environment;
import org.apache.ws.util.jndi.tools.Resource;
import org.apache.ws.util.jndi.tools.ResourceLink;
import org.apache.ws.util.jndi.tools.ResourceParameters;
import org.apache.wsfx.wsrf.jndi.config.EnvironmentDocument;
import org.apache.wsfx.wsrf.jndi.config.GlobalDocument;
import org.apache.wsfx.wsrf.jndi.config.JndiConfigDocument;
import org.apache.wsfx.wsrf.jndi.config.ParameterDocument;
import org.apache.wsfx.wsrf.jndi.config.ResourceDocument;
import org.apache.wsfx.wsrf.jndi.config.ResourceLinkDocument;
import org.apache.wsfx.wsrf.jndi.config.ResourceParamsDocument;
import org.apache.wsfx.wsrf.jndi.config.ServiceDocument;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

/**
* LOG-DONE JNDI Utiltiy methods for use with an XmlBean-generated JNDI-Config file. This class handles the initial
* setup of JNDI, it loads the JNDI config file and registers instances of services.
*
* @author Sal Campana
*/
public class XmlBeanJndiUtils
{
   private static Log LOG = LogFactory.getLog( XmlBeanJndiUtils.class.getName(  ) );

   /**
    * Apache JNDI URL Package Prefix
    */
   public static final String APACHE_URL_PKG_PREFIX = "org.apache.naming";

   /**
    * Apache JNDI Initial Context Factory Prefix
    */
   public static final String APACHE_INITIAL_CONTEXT_FACTORY = "org.apache.naming.java.javaURLContextFactory";

   /**
    * The file name of the jndi-config file.
    */
   public static final String       JNDI_CONFIG_FILENAME = "jndi-config.xml";
   private static final String      PROP_FACTORY      = "factory";
   private static boolean           s_configLoaded;
   private static boolean           s_jndiInitialized;
   private static DefaultParameters s_defaultParams;

   /**
    * Create all intermediate subcontexts.
    */
   public static Context createSubcontexts( Context currentContext,
                                            String  name )
   throws NamingException
   {
      StringTokenizer tokenizer = new StringTokenizer( name, "/" );

      while ( tokenizer.hasMoreTokens(  ) )
      {
         String token = tokenizer.nextToken(  );
         if ( ( !token.equals( "" ) ) && ( tokenizer.hasMoreTokens(  ) ) )
         {
            try
            {
               currentContext = currentContext.createSubcontext( token );
            }
            catch ( NameAlreadyBoundException e )
            {
               // Silent catch. Probably an object is already bound in
               // the context.
               currentContext = (Context) currentContext.lookup( token );
            }
         }
      }

      return currentContext;
   }

   /**
    * Initializes JNDI from a directory tree which contains the jndi-config.xml files....
    *
    * @param configDir
    * @return
    * @throws Exception
    */
   public static synchronized Context initFromDir( String configDir )
   throws Exception
   {
      if ( !s_configLoaded )
      {
         LOG.debug( "Initializing JNDI from config directory: " + configDir + " ..." );

         initJNDI(  );

         File   fDir = new File( configDir );
         File[] dirs =
            fDir.listFiles( new FileFilter(  )
               {
                  public boolean accept( File path )
                  {
                     return path.isDirectory(  );
                  }
               } );

         for ( int i = 0; i < dirs.length; i++ )
         {
            processJNDIFile( dirs[i], JNDI_CONFIG_FILENAME );
         }

         s_configLoaded = true;
      }

      return new InitialContext(  );
   }

   /**
    * Initializes JNDI given a File name which will attempt to be loaded.
    *
    * @param configFilename
    * @return
    * @throws Exception
    */
   public static synchronized Context initFromFile( String configFilename )
   throws Exception
   {
      LOG.debug( "Initializing JNDI from file: " + configFilename );
      if ( !s_configLoaded )
      {
         initJNDI(  );

         InputStream configInput;
         try
         {
            LOG.debug( "Trying to load JNDI configuration from file: " + configFilename );
            configInput = new FileInputStream( configFilename );
         }
         catch ( FileNotFoundException fnfe )
         {
            LOG.debug( "Trying to load JNDI configuration from classloader resource: " + configFilename );
            configInput = XmlBeanJndiUtils.class.getClassLoader(  ).getResourceAsStream( configFilename );
            if ( configInput == null )
            {
               throw new IOException( "jndiConfigNotFound" );
            }
         }

         Context context = new InitialContext(  );
         parseJNDIConfig( context, configInput );
         s_configLoaded = true;
      }

      return new InitialContext(  );
   }

   /**
    * Initializes JNDI from a given InputStream to a jndi-config.xml file.
    *
    * @param inputStream
    * @return JNDI Context
    * @throws Exception
    */
   public static synchronized Context initFromInputStream( InputStream inputStream )
   throws Exception
   {
      if ( !s_configLoaded )
      {
         initJNDI(  );
         LOG.debug( "Trying to load JNDI configuration from inputstream" );
         parseJNDIConfig( new InitialContext(  ),
                          inputStream );
         s_configLoaded = true;
      }

      return new InitialContext(  );
   }

   /**
    * Configure JNDI with the Apache Tomcat naming service classes and
    * create the WSRF context.
    *
    * @return the WSRF context
    * @throws Exception
    */
   public static synchronized Context initJNDI(  )
   throws Exception
   {
      if ( !s_jndiInitialized )
      {
         initJndiImpl(  );
         initWsrfContext(  );
         s_jndiInitialized = true;
      }

      return new InitialContext(  );
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    *
    * @throws NamingException DOCUMENT_ME
    */
   public static Context initWsrfContext(  )
   throws NamingException
   {
      Context        wsrfContext;
      InitialContext initialContext = new InitialContext(  );
      try
      {
         wsrfContext = (Context) initialContext.lookup( JndiConstants.CONTEXT_NAME_WSRF );
      }
      catch ( NameNotFoundException nnfe )
      {
         LOG.debug( "Initializing WSRF JNDI context..." );
         LOG.debug( "Creating JNDI subcontext: " + JndiConstants.CONTEXT_NAME_WSRF + " ..." );
         wsrfContext = initialContext.createSubcontext( JndiConstants.CONTEXT_NAME_WSRF );
         LOG.debug( "Creating JNDI subcontext: " + JndiConstants.ATOMIC_NAME_SERVICES + " ..." );
         wsrfContext.createSubcontext( JndiConstants.ATOMIC_NAME_SERVICES );
         LOG.debug( "Creating JNDI subcontext: " + JndiConstants.ATOMIC_NAME_GLOBAL + " ..." );
         wsrfContext.createSubcontext( JndiConstants.ATOMIC_NAME_GLOBAL );
      }

      return wsrfContext;
   }

   /**
    * Retrieves the named object on the specified context. The object returned must be of assignable from the type
    * specified.
    *
    * @param context the context to perform lookup on
    * @param name    the name of the object to lookup
    * @param type    the expected type of the object returned
    */
   public static Object lookup( Context context,
                                String  name,
                                Class   type )
   throws NamingException
   {
      if ( context == null )
      {
         throw new IllegalArgumentException( "nullArgument:context" );
      }

      if ( type == null )
      {
         throw new IllegalArgumentException( "nullArgument:type" );
      }

      Object tmp = context.lookup( name );
      if ( type.isAssignableFrom( tmp.getClass(  ) ) )
      {
         return tmp;
      }
      else
      {
         throw new NamingException( "expectedType " + type.getName(  ) );
      }
   }

   /**
    * Called via parseJNDIConfig(InputStream)
    * <p/>
    * Parse the given JNDI configuration and populate the JNDI registry using the parsed configuration
    *
    * @param configStream The configuration stream to parse
    * @throws Exception
    */
   public static void parseJNDIConfig( Context     initContext,
                                       InputStream configStream )
   throws Exception
   {
      if ( configStream == null )
      {
         throw new IllegalArgumentException( "nullJNDIConfigInput" );
      }

      if ( initContext == null )
      {
         throw new IllegalArgumentException(  );
      }

      //get the global context
      Context              envContext    = (Context) initContext.lookup( JndiConstants.CONTEXT_NAME_GLOBAL );
      XmlBeanNamingContext namingContext = new XmlBeanNamingContext( envContext );

      //load the config file
      XmlOptions options = new XmlOptions(  );
      options.setLoadStripWhitespace(  );
      JndiConfigDocument jndiConfigDoc = (JndiConfigDocument) XmlObject.Factory.parse( configStream, options );
      validateJndiConfig( jndiConfigDoc );
      JndiConfigDocument.JndiConfig jndiConfig = jndiConfigDoc.getJndiConfig(  );
      GlobalDocument.Global         global = jndiConfig.getGlobal(  );

      //setup the global jndi elements
      addGlobalElements( namingContext, global );

      //get the service context
      envContext       = (Context) initContext.lookup( JndiConstants.CONTEXT_NAME_SERVICES );
      namingContext    = new XmlBeanNamingContext( envContext );

      //setup the service jndi elements
      ServiceDocument.Service[] serviceArray = jndiConfig.getServiceArray(  );
      addServiceElements( namingContext, serviceArray );
   }

   private static void setDefaultParameterValues( ResourceParameters params )
   {
      if ( params.getParameter( PROP_FACTORY ) == null )
      {
         params.addParameter( PROP_FACTORY,
                              s_defaultParams.getFactory(  ) );
      }
   }

   private static DefaultParameters getDefaultProperties( GlobalDocument.Global global )
   throws IllegalAccessException,
          InstantiationException,
          ClassNotFoundException
   {
      ResourceDocument.Resource   defaultConfig = null;
      ResourceDocument.Resource[] resourceArray = global.getResourceArray(  );
      for ( int i = 0; i < resourceArray.length; i++ )
      {
         ResourceDocument.Resource resource = resourceArray[i];
         if ( DefaultParameters.class.getName(  ).equals( resource.getType(  ) ) )
         {
            defaultConfig = resource;
            break;
         }
      }

      return setupDefaultParams( defaultConfig );
   }

   private static Environment[] getEnvironmentArray( EnvironmentDocument.Environment[] environmentArray )
   {
      List envList = new ArrayList(  );

      if ( environmentArray != null )
      {
         for ( int i = 0; i < environmentArray.length; i++ )
         {
            EnvironmentDocument.Environment environment = environmentArray[i];
            Environment                     env = new Environment(  );
            env.setDescription( environment.getDescription(  ) );
            env.setName( environment.getName(  ) );
            env.setType( environment.getType(  ) );
            env.setValue( environment.getValue(  ) );
            envList.add( env );
         }
      }

      return (Environment[]) envList.toArray( new Environment[0] );
   }

   private static ResourceLink[] getResourceLinkArray( ResourceLinkDocument.ResourceLink[] resourceLinkArray )
   {
      List resourceLinks = new ArrayList(  );
      if ( resourceLinkArray != null )
      {
         for ( int i = 0; i < resourceLinkArray.length; i++ )
         {
            ResourceLinkDocument.ResourceLink resourceLink = resourceLinkArray[i];
            ResourceLink                      link = new ResourceLink(  );
            link.setName( resourceLink.getName(  ) );
            link.setTarget( resourceLink.getTarget(  ) );
            resourceLinks.add( link );
         }
      }

      return (ResourceLink[]) resourceLinks.toArray( new ResourceLink[0] );
   }

   private static ConfigContext[] getServiceArray( ServiceDocument.Service[] serviceArray,
                                                   XmlBeanNamingContext      namingContext )
   {
      List services = new ArrayList(  );
      if ( serviceArray != null )
      {
         for ( int i = 0; i < serviceArray.length; i++ )
         {
            ServiceDocument.Service service = serviceArray[i];
            ConfigContext           context = new ConfigContext(  );
            context.setName( service.getName(  ) );
            Environment[] environmentArray = getEnvironmentArray( service.getEnvironmentArray(  ) );
            for ( int j = 0; j < environmentArray.length; j++ )
            {
               context.addEnvironment( environmentArray[j] );
            }

            Resource[] resourceArray =
               createResources( service.getResourceArray(  ),
                                service.getName(  ),
                                namingContext );
            for ( int j = 0; j < resourceArray.length; j++ )
            {
               Resource           resource = resourceArray[j];
               ResourceParameters params = resource.getParameters(  );
               setDefaultParameterValues( params );
               validateParameterValues( params );
            }

            for ( int j = 0; j < resourceArray.length; j++ )
            {
               context.addResource( resourceArray[j] );
            }

            ResourceLink[] resourceLinkArray = getResourceLinkArray( service.getResourceLinkArray(  ) );
            for ( int j = 0; j < resourceLinkArray.length; j++ )
            {
               context.addResourceLink( resourceLinkArray[j] );
            }

            services.add( context );
         }
      }

      return (ConfigContext[]) services.toArray( new ConfigContext[0] );
   }

   private static ConfigContext[] getServiceSubContextArray( ConfigContext service )
   {
      List subContexts = new ArrayList(  );
      if ( service != null )
      {
         Set      subContextNames = service.getSubContextNames(  );
         Iterator iterator = subContextNames.iterator(  );

         while ( iterator.hasNext(  ) )
         {
            subContexts.add( service.getSubContext( (String) iterator.next(  ) ) );
         }
      }

      return (ConfigContext[]) subContexts.toArray( new ConfigContext[0] );
   }

   private static void addGlobalElements( XmlBeanNamingContext  namingContext,
                                          GlobalDocument.Global global )
   throws NamingException,
          IllegalAccessException,
          ClassNotFoundException,
          InstantiationException
   {
      if ( global != null )
      {
         s_defaultParams = getDefaultProperties( global );

         Environment[] environmentArray = getEnvironmentArray( global.getEnvironmentArray(  ) );

         for ( int i = 0; i < environmentArray.length; i++ )
         {
            namingContext.addEnvironment( environmentArray[i] );
         }

         ConfigContext[] subContext = getServiceArray( global.getServiceArray(  ),
                                                       namingContext );
         for ( int i = 0; i < subContext.length; i++ )
         {
            namingContext.addSubContext( subContext[i] );
         }

         Resource[] resourceArray = createResources( global.getResourceArray(  ),
                                                     null,
                                                     namingContext );
         for ( int i = 0; i < resourceArray.length; i++ )
         {
            namingContext.addResource( resourceArray[i] );
         }

         ResourceLink[] resourceLinkArray = getResourceLinkArray( global.getResourceLinkArray(  ) );
         for ( int i = 0; i < resourceLinkArray.length; i++ )
         {
            namingContext.addResourceLink( resourceLinkArray[i] );
         }
      }
   }

   private static void addServiceElements( XmlBeanNamingContext      namingContext,
                                           ServiceDocument.Service[] serviceArray )
   throws NamingException
   {
      if ( serviceArray != null )
      {
         ConfigContext[] services = getServiceArray( serviceArray, namingContext );
         for ( int i = 0; i < services.length; i++ )
         {
            ConfigContext service = services[i];
            namingContext.addService( service );
            ConfigContext[] serviceSubContextArray = getServiceSubContextArray( service );
            for ( int j = 0; j < serviceSubContextArray.length; j++ )
            { //todo not sure if defaults bubble down here...
               namingContext.addSubContext( serviceSubContextArray[j] );
            }
         }
      }
   }

   private static void checkValueIsNonEmpty( ResourceParameters params,
                                             String             paramName )
   {
      String paramValue = params.getParameter( paramName );
      if ( paramValue.trim(  ).equals( "" ) )
      {
         throw new RuntimeException( paramName + " parameter must have a non-empty value!" );
      }
   }

   private static ResourceParameters createResourceParameters( ResourceParamsDocument.ResourceParams resourceParams )
   {
      ResourceParameters params = new ResourceParameters(  );
      if ( resourceParams != null )
      {
         ParameterDocument.Parameter[] parameterArray = resourceParams.getParameterArray(  );
         for ( int i = 0; i < parameterArray.length; i++ )
         {
            ParameterDocument.Parameter parameter = parameterArray[i];
            params.addParameter( parameter.getName(  ),
                                 parameter.getValue(  ) );
         }
      }

      return params;
   }

   private static Resource[] createResources( ResourceDocument.Resource[] resourceArray,
                                              String                      name,
                                              XmlBeanNamingContext        namingContext )
   {
      List resources = new ArrayList(  );
      if ( resourceArray != null )
      {
         for ( int i = 0; i < resourceArray.length; i++ )
         {
            ResourceDocument.Resource resourceDoc = resourceArray[i];

            /* //special type of resource....metatdata...handle differently....
               MetadataConfigDocument.MetadataConfig metadataConfig = resourceDoc.getMetadataConfig();
               if (metadataConfig != null)
               {
                   Constructor constructor = null;
                   MetadataConfig metaConfig = null;
                   try
                   {
                       Class metaConfigClass = Class.forName(resourceDoc.getType());
                       constructor =
                       metaConfigClass.getConstructor(new Class[]
                       {
                           MetadataConfigDocument.MetadataConfig.class
                       });
                       metaConfig =
                       (MetadataConfig) constructor.newInstance(new Object[]
                       {
                           metadataConfig
                       });
                   }
                   catch (Exception e)
                   {
                       LOG.error("Unable to find constructor which takes: " + metadataConfig.getClass().getName()
                                 + ", in MetadataConfig object: " + resourceDoc.getType()
                                 + ".  The metadata will be ignored!", e);
                   }
           
                                   if (metaConfig != null)
                                   {
                                       String contextName = null;
                                       if (name != null)
                                       {
           
                                           try
                                           {
                                               createSubcontexts(namingContext.getContext(), name); //add subcontext
                                               contextName = contextName + resourceDoc.getName();
                                               namingContext.bind(contextName, metaConfig);
                                           }
                                           catch (NamingException e)
                                           {
                                               LOG.error("A NamingException occurred when creating sbucontexts for the Metadataconfig.", e);
                                           }
                                           contextName = name + "/";
                                       }
                                   }
                                   continue;
                               }
             */
            Resource resource = new Resource(  );
            resource.setName( resourceDoc.getName(  ) );
            resource.setAuth( resourceDoc.getAuth(  ) );
            resource.setDescription( resourceDoc.getDescription(  ) );
            resource.setType( resourceDoc.getType(  ) );
            resource.setScope( resourceDoc.getScope(  ) );
            resource.setParameters( createResourceParameters( resourceDoc.getResourceParams(  ) ) );
            resources.add( resource );
         }
      }

      return (Resource[]) resources.toArray( new Resource[0] );
   }

   private static void initJndiImpl(  )
   {
      String apacheUrlPrefix      = APACHE_URL_PKG_PREFIX;
      String systemUrlPrefix      = System.getProperty( Context.URL_PKG_PREFIXES );
      String systemContextFactory = System.getProperty( Context.INITIAL_CONTEXT_FACTORY );

      if ( ( systemContextFactory == null ) && ( systemUrlPrefix == null ) )
      {
         System.setProperty( Context.URL_PKG_PREFIXES, apacheUrlPrefix );
         System.setProperty( Context.INITIAL_CONTEXT_FACTORY, APACHE_INITIAL_CONTEXT_FACTORY );
      }
   }

   private static void processJNDIFile( File   dir,
                                        String configFile )
   throws Exception
   {
      Context context = new InitialContext(  );
      File    file = new File( dir, configFile );
      if ( !file.exists(  ) )
      {
         return;
      }

      LOG.debug( "Loading JNDI configuration from file: " + file + " ..." );

      InputStream in = null;
      try
      {
         in = new FileInputStream( file );
         parseJNDIConfig( context, in );
      }
      finally
      {
         if ( in != null )
         {
            try
            {
               in.close(  );
            }
            catch ( IOException ioe )
            {
               // ignore
            }
         }
      }
   }

   private static DefaultParameters setupDefaultParams( ResourceDocument.Resource defaultConfig )
   throws ClassNotFoundException,
          IllegalAccessException,
          InstantiationException
   {
      DefaultParameters defaultParams = null;
      if ( defaultConfig != null )
      {
         Object defaultConf = Class.forName( defaultConfig.getType(  ) ).newInstance(  );
         if ( defaultConf instanceof DefaultParameters )
         {
            defaultParams = (DefaultParameters) defaultConf;
            ResourceParamsDocument.ResourceParams resourceParams = defaultConfig.getResourceParams(  );
            ParameterDocument.Parameter[]         parameterArray = resourceParams.getParameterArray(  );
            for ( int i = 0; i < parameterArray.length; i++ )
            {
               ParameterDocument.Parameter parameter = parameterArray[i];
               String                      name  = parameter.getName(  );
               String                      value = parameter.getValue(  );

               if ( ( value != null ) && !value.equals( "" ) )
               {
                  if ( PROP_FACTORY.equals( name ) )
                  {
                     defaultParams.setFactory( value );
                  }
               }
            }
         }
      }

      return defaultParams;
   }

   private static void validateJndiConfig( XmlObject requestXBean )
   {
      XmlOptions validateOptions = new XmlOptions(  );
      List       errorList = new ArrayList(  );
      validateOptions.setErrorListener( errorList );
      boolean isValid = requestXBean.validate( validateOptions );
      if ( !isValid )
      {
         StringBuffer strBuf = new StringBuffer( "jndi-config.xml is not valid as per its schema: \n\n" );
         for ( int i = 0; i < errorList.size(  ); i++ )
         {
            strBuf.append( "\t\t" );
            strBuf.append( i + 1 );
            strBuf.append( ") " );
            strBuf.append( errorList.get( i ) );
            strBuf.append( "\n" );
         }

         strBuf.append( "\n" );
         LOG.fatal( strBuf.toString(  ) );
      }
   }

   private static void validateParameterValues( ResourceParameters params )
   {
      checkValueIsNonEmpty( params, PROP_FACTORY );
   }
}
TOP

Related Classes of org.apache.ws.util.jndi.XmlBeanJndiUtils

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.