org.globus.security.gridmap.GridMap.java Source code

Java tutorial

Introduction

Here is the source code for org.globus.security.gridmap.GridMap.java

Source

/*
 * Portions of this file Copyright 1999-2005 University of Chicago
 * Portions of this file Copyright 1999-2005 The University of Southern California.
 *
 * This file or a portion of this file is licensed under the
 * terms of the Globus Toolkit Public License, found at
 * http://www.globus.org/toolkit/download/license.html.
 * If you redistribute this file, with or without
 * modifications, you must include this notice in the file.
 */
package org.globus.security.gridmap;

import java.util.Map;
import java.util.Vector;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.Serializable;

import org.globus.util.QuotedStringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class GridMap implements Serializable {

    private static Log logger = LogFactory.getLog(GridMap.class.getName());

    private static final String COMMENT_CHARS = "#";
    // keywords that need to be replaced
    private static final char[] EMAIL_KEYWORD_1 = { 'e', '=' };
    private static final char[] EMAIL_KEYWORD_2 = { 'e', 'm', 'a', 'i', 'l', '=' };
    private static final char[] UID_KEYWORD = { 'u', 'i', 'd', '=' };
    // Length of key words that need to be replaced
    private static final int EMAIL_KEYWORD_1_L = 2;
    private static final int EMAIL_KEYWORD_2_L = 6;
    private static final int UID_KEYWORD_L = 4;
    // Keywords to be replaced with.
    private static final String EMAIL_KEYWORD = "emailaddress=";
    private static final String USERID_KEYWORD = "userid=";

    protected Map map;

    // the file the grim map was loaded from
    private File file;
    // last time the file was modified
    private long lastModified;
    // log or throw exception on bad entries 
    private boolean ignoreErrors = false;

    /**
     * Sets whether errors in the gridmap file
     * should be ignored. Errors are not ignored by default.
     * 
     * @param ignoreErrors if true, errors in the gridmap file
     *        will be ignored (warnings will be logged). If false,
     *        an exception will be raised on errors. 
     */
    public void setIgnoreErrors(boolean ignoreErrors) {
        this.ignoreErrors = ignoreErrors;
    }

    /**
     * Returns whether errors in the gridmap file are
     * ignored.
     *
     * @return true if errors in the gridmap file are ignored.
     *         False, otherwise.
     */
    public boolean getIgnoreErrors() {
        return this.ignoreErrors;
    }

    /**
     * Loads grid map definition from a given 
     * file. 
     * 
     * @param file grid map file
     * @exception IOException in case of I/O or 
     *            parsing error.
     */
    public void load(String file) throws IOException {
        load(new File(file));
    }

    /**
     * Loads grid map definition from a given 
     * file. 
     * 
     * @param file grid map file
     * @exception IOException in case of I/O or 
     *            parsing error.
     */
    public void load(File file) throws IOException {
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            this.file = file;
            this.lastModified = file.lastModified();
            load(in);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                }
            }
        }
    }

    /**
     * Reloads the gridmap from a file only if the gridmap
     * was initially loaded using the {@link #load(File) 
     * load} or {@link #load(String) load} functions.
     * The file will only be reloaded if it has changed
     * since the last time. 
     *
     * @exception IOException in case of I/O error during
     *            reload.
     */
    public void refresh() throws IOException {
        if (this.file == null) {
            return;
        }
        if (this.file.lastModified() != this.lastModified) {
            load(this.file);
        }
    }

    /**
     * Loads grid map file definition from a given
     * input stream. The input stream is not closed
     * in case of an error.
     *
     * @param input input stream containing grid map 
     *        definitions.
     * @exception IOException in case of I/O error or
     *            parsing error.
     */
    public void load(InputStream input) throws IOException {
        String line;

        BufferedReader reader = new BufferedReader(new InputStreamReader(input));

        Map localMap = new HashMap();
        GridMapEntry entry;
        QuotedStringTokenizer tokenizer;
        StringTokenizer idTokenizer;

        while ((line = reader.readLine()) != null) {
            line = line.trim();
            if ((line.length() == 0) || (COMMENT_CHARS.indexOf(line.charAt(0)) != -1)) {
                continue;
            }

            tokenizer = new QuotedStringTokenizer(line);

            String globusID = null;

            if (tokenizer.hasMoreTokens()) {
                globusID = tokenizer.nextToken();
            } else {
                if (this.ignoreErrors) {
                    logger.warn("Globus ID missing: " + line);
                    continue;
                } else {
                    throw new IOException("Globus ID missing: " + line);
                }
            }

            String userIDs = null;

            if (tokenizer.hasMoreTokens()) {
                userIDs = tokenizer.nextToken();
            } else {
                if (this.ignoreErrors) {
                    logger.warn("User ID mapping missing: " + line);
                    continue;
                } else {
                    throw new IOException("User ID mapping missing: " + line);
                }
            }

            idTokenizer = new StringTokenizer(userIDs, ",");
            String[] ids = new String[idTokenizer.countTokens()];
            int i = 0;
            while (idTokenizer.hasMoreTokens()) {
                ids[i++] = idTokenizer.nextToken();
            }

            String normalizedDN = normalizeDN(globusID);
            entry = (GridMapEntry) localMap.get(normalizedDN);
            if (entry == null) {
                entry = new GridMapEntry();
                entry.setGlobusID(globusID);
                entry.setUserIDs(ids);
                localMap.put(normalizedDN, entry);
            } else {
                entry.addUserIDs(ids);
            }
        }

        this.map = localMap;
    }

    /**
     * Returns first local user name mapped to the specified 
     * globusID.
     * 
     * @param globusID globusID
     * @return local user name for the specified globusID.
     *         Null if the globusID is not mapped
     *         to a local user name. 
     */
    public String getUserID(String globusID) {
        String[] ids = getUserIDs(globusID);
        if (ids != null && ids.length > 0) {
            return ids[0];
        } else {
            return null;
        }
    }

    /**
     * Returns local user names mapped to the specified
     * globusID.
     *
     * @param globusID globusID
     * @return array of local user names for the specified globusID.
     *         Null if the globusID is not mapped
     *         to any local user name.
     */
    public String[] getUserIDs(String globusID) {
        if (globusID == null) {
            throw new IllegalArgumentException("globusID is null");
        }

        if (this.map == null) {
            return null;
        }

        GridMapEntry entry = (GridMapEntry) this.map.get(normalizeDN(globusID));
        return (entry == null) ? null : entry.getUserIDs();
    }

    /**
     * Checks if a given globus ID is associated with given
     * local user account.
     *
     * @param globusID globus ID
     * @param userID userID
     * @return true if globus ID is associated with given local
     *         user account, false, otherwise.
     */
    public boolean checkUser(String globusID, String userID) {
        if (globusID == null) {
            throw new IllegalArgumentException("globusID is null");
        }
        if (userID == null) {
            throw new IllegalArgumentException("userID is null");
        }

        if (this.map == null) {
            return false;
        }

        GridMapEntry entry = (GridMapEntry) this.map.get(normalizeDN(globusID));
        return (entry == null) ? false : entry.containsUserID(userID);
    }

    /**
     * Returns globus ID associated with the
     * specified local user name.
     *
     * @param userID local user name
     * @return associated globus ID, null
     *         if there is not any.
     */
    public String getGlobusID(String userID) {
        if (userID == null) {
            throw new IllegalArgumentException("userID is null");
        }

        if (this.map == null) {
            return null;
        }

        Iterator iter = this.map.entrySet().iterator();
        Map.Entry mapEntry;
        GridMapEntry entry;
        while (iter.hasNext()) {
            mapEntry = (Map.Entry) iter.next();
            entry = (GridMapEntry) mapEntry.getValue();
            if (entry.containsUserID(userID)) {
                return entry.getGlobusID();
            }
        }
        return null;
    }

    /**
     * Returns all globus IDs associated with the
     * specified local user name.
     *
     * @param userID local user name
     * @return associated globus ID, null
     *         if there is not any.
     */
    public String[] getAllGlobusID(String userID) {
        if (userID == null) {
            throw new IllegalArgumentException("userID is null");
        }

        if (this.map == null) {
            return null;
        }

        Vector v = new Vector();

        Iterator iter = this.map.entrySet().iterator();
        Map.Entry mapEntry;
        GridMapEntry entry;
        while (iter.hasNext()) {
            mapEntry = (Map.Entry) iter.next();
            entry = (GridMapEntry) mapEntry.getValue();
            if (entry.containsUserID(userID)) {
                v.add(entry.getGlobusID());
            }
        }

        // create array of strings and add values back in
        if (v.size() == 0) {
            return null;
        }

        String idS[] = new String[v.size()];
        for (int ctr = 0; ctr < v.size(); ctr++) {
            idS[ctr] = (String) v.elementAt(ctr);
        }

        return idS;
    }

    public void map(String globusID, String userID) {
        if (globusID == null) {
            throw new IllegalArgumentException("globusID is null");
        }
        if (userID == null) {
            throw new IllegalArgumentException("userID is null");
        }

        if (this.map == null) {
            this.map = new HashMap();
        }

        String normalizedDN = normalizeDN(globusID);

        GridMapEntry entry = (GridMapEntry) this.map.get(normalizedDN);
        if (entry == null) {
            entry = new GridMapEntry();
            entry.setGlobusID(globusID);
            entry.setUserIDs(new String[] { userID });
            this.map.put(normalizedDN, entry);
        } else {
            entry.addUserID(userID);
        }
    }

    static class GridMapEntry implements Serializable {
        String globusID;
        String[] userIDs;

        public String getFirstUserID() {
            return userIDs[0];
        }

        public String[] getUserIDs() {
            return userIDs;
        }

        public String getGlobusID() {
            return globusID;
        }

        public void setGlobusID(String globusID) {
            this.globusID = globusID;
        }

        public void setUserIDs(String[] userIDs) {
            this.userIDs = userIDs;
        }

        public boolean containsUserID(String userID) {
            if (userID == null) {
                return false;
            }
            for (int i = 0; i < userIDs.length; i++) {
                if (userIDs[i].equalsIgnoreCase(userID)) {
                    return true;
                }
            }
            return false;
        }

        public void addUserID(String userID) {
            if (containsUserID(userID))
                return;
            String[] ids = new String[userIDs.length + 1];
            System.arraycopy(userIDs, 0, ids, 0, userIDs.length);
            ids[userIDs.length] = userID;
            userIDs = ids;
        }

        public void addUserIDs(String[] userIDs) {
            for (int i = 0; i < userIDs.length; i++) {
                addUserID(userIDs[i]);
            }
        }

    }

    private static boolean keyWordPresent(char[] args, int startIndex, char[] keyword, int length) {

        if (startIndex + length > args.length) {
            return false;
        }

        int j = startIndex;
        for (int i = 0; i < length; i++) {
            if (args[j] != keyword[i]) {
                return false;
            }
            j++;
        }
        return true;
    }

    public static String normalizeDN(String globusID) {

        if (globusID == null) {
            return null;
        }

        globusID = globusID.toLowerCase();
        char[] globusIdChars = globusID.toCharArray();

        StringBuffer normalizedDN = new StringBuffer();

        int i = 0;

        while (i < globusIdChars.length) {

            if (globusIdChars[i] == '/') {

                normalizedDN.append("/");

                if (keyWordPresent(globusIdChars, i + 1, EMAIL_KEYWORD_1, EMAIL_KEYWORD_1_L)) {
                    normalizedDN.append(EMAIL_KEYWORD);
                    i = i + EMAIL_KEYWORD_1_L;
                } else if (keyWordPresent(globusIdChars, i + 1, EMAIL_KEYWORD_2, EMAIL_KEYWORD_2_L)) {
                    normalizedDN.append(EMAIL_KEYWORD);
                    i = i + EMAIL_KEYWORD_2_L;
                } else if (keyWordPresent(globusIdChars, i + 1, UID_KEYWORD, UID_KEYWORD_L)) {
                    normalizedDN.append(USERID_KEYWORD);
                    i = i + UID_KEYWORD_L;
                }
                i++;
            } else {
                normalizedDN.append(globusIdChars[i]);
                i++;
            }
        }

        return normalizedDN.toString();
    }
}