com.ritchey.naming.InitialContextFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.ritchey.naming.InitialContextFactory.java

Source

package com.ritchey.naming;
// ========================================================================

// $Id: InitialContextFactory.java 1327 2006-11-27 18:40:14Z janb $
// Copyright 1999-2006 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.
// ========================================================================

import java.io.FileInputStream;
import java.util.Hashtable;
import java.util.Properties;

import javax.naming.Binding;
import javax.naming.CompoundName;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;

import org.eclipse.jetty.jndi.local.localContextRoot;

import com.ritchey.shared.Log;
import java.util.logging.Level;
import java.util.logging.Logger;

/*------------------------------------------------*/
/**
 * InitialContextFactory.java
 *
 * Factory for the default InitialContext. Created: Tue Jul 1 19:08:08 2003
 *
 * @author <a href="mailto:janb@mortbay.com">Jan Bartel</a>
 * @version 1.0
 *
 *
 * Example build.properties snippet
 *
 * database.jndi.names=progress,powercampus
 *
 * database.powercampus.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
 * database.powercampus.user=sa database.powercampus.password=mySaPassword
 * database.powercampus.url=jdbc:sqlserver://kindness;ServerName=kindness.lcunet.lcu.edu\\powercampus;databaseName=Area51
 *
 * database.progress.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
 * database.progress.user=sa database.progress.password=mySaPassword
 * database.progress.url=jdbc:sqlserver://kindness;ServerName=kindness.lcunet.lcu.edu\\powercampus;databaseName=forms_TEST
 */
public class InitialContextFactory implements javax.naming.spi.InitialContextFactory {

    public static class DefaultParser implements NameParser {

        static Properties syntax = new Properties();

        static {
            syntax.put("jndi.syntax.direction", "left_to_right");
            syntax.put("jndi.syntax.separator", "/");
            syntax.put("jndi.syntax.ignorecase", "false");
        }

        public Name parse(String name) throws NamingException {
            return new CompoundName(name, syntax);
        }
    };

    /*------------------------------------------------*/
    /**
     * Get Context that has access to default Namespace. This method won't be
     * called if a name URL beginning with java: is passed to an InitialContext.
     *
     * @see org.mortbay.naming.java.javaURLContextFactory
     * @param env a <code>Hashtable</code> value
     * @return a <code>Context</code> value
     */
    public Context getInitialContext(Hashtable env) {
        Log.debug("InitialContext loaded");
        Context ctx = new localContextRoot(env);

        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("build.properties"));
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        Context jdbc = null;
        try {
            jdbc = ctx.createSubcontext("jdbc");
        } catch (NamingException e) {
            try {
                jdbc = (Context) ctx.lookup("jdbc");
            } catch (NamingException e1) {
                e1.printStackTrace();
            }
        }
        Context ldap = null;
        try {
            ldap = ctx.createSubcontext("ldap");
        } catch (NamingException e) {
            try {
                ldap = (Context) ctx.lookup("ldap");
            } catch (NamingException e1) {
                e1.printStackTrace();
            }
        }

        Log.debug("getInitialContext");

        String databaseNames = properties.getProperty("database.jndi.names");
        if (databaseNames == null) {
            Log.warn(new RuntimeException("database.jndi.names is not defined"
                    + " in build.properties as a comma separated list in " + "build.properties"));
            return ctx;
        }

        for (String database : databaseNames.split(" *, *")) {
            Log.debug("create " + database);
            try {
                createDs(database, properties, jdbc);
            } catch (NamingException e) {
                e.printStackTrace();
            }
        }

        try {
            createLdapStrings(properties, ldap);
        } catch (NamingException e1) {
            e1.printStackTrace();
        }

        String url = getValue(false, "picture", null, properties);
        try {
            ctx.bind("picture", url);
        } catch (NamingException ex) {
            Logger.getLogger(InitialContextFactory.class.getName()).log(Level.SEVERE, null, ex);
        }

        try {
            Log.debug("jdbc initial context = " + ctx.listBindings("jdbc"));
            NamingEnumeration<Binding> ldapBindings = ctx.listBindings("ldap");
            Log.debug("ldap initial context = " + ctx.listBindings("ldap"));
            while (ldapBindings.hasMore()) {
                Binding binding = ldapBindings.next();
                Log.debug("binding: " + binding.getName());
            }
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return ctx;
    }

    public void createLdapStrings(Properties properties, Context ldap) throws NamingException {
        Boolean isDatabase = false;

        ldap.bind("url", getValue(isDatabase, "url", "ldap", properties));
        ldap.bind("bindUserDistinguishedName",
                getValue(isDatabase, "bindUserDistinguishedName", "ldap", properties));
        ldap.bind("bindUserPassword", getValue(isDatabase, "bindUserPassword", "ldap", properties));

        ldap.bind("usersSearchRoot", getValue(isDatabase, "usersSearchRoot", "ldap", properties));
        ldap.bind("groupsSearchRoot", getValue(isDatabase, "groupsSearchRoot", "ldap", properties));
        ldap.bind("groupsSearchRootSecondary",
                getValue(isDatabase, "groupsSearchRootSecondary", "ldap", properties));

    }

    /**
     * Create a databaseSource for a database by using properties that are
     * formed with the jndi name (e.g. database.myCoolDatabaseNumber1.url). url,
     * user, password and driver should all be defined.
     *
     * @param database is the jndi name of the database
     * @param properties represents the values of build.properties
     * @param jdbc is the context we're going to load
     * @throws NamingException
     */
    public void createDs(String database, Properties properties, Context jdbc) throws NamingException {
        org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
        try {
            jdbc.bind(database, ds);
        } catch (Exception e) {
            // Quietly suppress NameAlreadyBound Exception
        }

        Boolean isDatabase = true;
        ds.setDriverClassName(getValue(isDatabase, "driver", database, properties));
        ds.setUrl(getValue(isDatabase, "url", database, properties));
        ds.setUsername(getValue(isDatabase, "user", database, properties));
        ds.setPassword(getValue(isDatabase, "password", database, properties));
    }

    /**
     * return the build.properties values for a base name
     *
     * @param base database.{databaseName}.{base}={value} should be setup in
     * build.properties
     * @param databaseName
     * @param properties represents build.properties settings
     * @return the value of the property from build.properties
     */
    String getValue(Boolean database, String propertyName, String sectionName, Properties properties) {
        String name = ((sectionName != null) ? sectionName + "." : "") + propertyName;
        if (database) {
            name = "database." + name;
        }
        String value = (String) properties.getProperty(name);
        if (value == null) {
            Log.warn(new RuntimeException(name + " is not defined in build.properties"));
        }
        return value;
    }

}