/*
 * @(#)StaticFields.java    2.5.0   26 April 2006
 *
 * Copyright 2006
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.util;

import edu.neu.ccs.quick.*;

import java.util.*;
import java.lang.reflect.*;

/**
 * <p>The class <code>StaticFields</code> contains a
 * general static method to extract the public static
 * fields from a given class with given field type.</p>
 * 
 * <p>The class also contains two special static methods
 * that deal with a field whose type is int.</p>
 * 
 * <p>This class cannot be instantiated.</p>
 *
 * @author  Richard Rasala
 * @version 2.5.0
 * @since   2.5.0
 */
public class StaticFields
{
    /** Prevent instantiation. */
    private StaticFields() {}
    
    
    /**
     * <p>Returns the public static fields
     * in the given class
     * of the given field type.</p>
     * 
     * <p>Returns <code>null</code> if type
     * is <code>null</code>.</p>
     * 
     * <p>Returns all public static fields if
     * fieldtype is <code>null</code>.</p>
     * 
     * @param type the class type to inspect
     * @param fieldtype the field type of the
     *    desired public static fields
     */
    public static Field[]
        getPublicStaticFields
            (Class type, Class fieldtype)
    {
        if (type == null)
            return null;
        
        Field[] fields = type.getDeclaredFields();
        
        int N = fields.length;
        
        Vector vector = new Vector();
        
        for (int i = 0; i < N; i++) {
            Field field = fields[i];
            
            int modifiers = field.getModifiers();
            
            if (! Modifier.isPublic(modifiers))
                continue;
            
            if (! Modifier.isStatic(modifiers))
                continue;
            
            if (fieldtype != null)
                if (! (field.getType() == fieldtype))
                    continue;
            
            vector.add(field);
        }
        
        return (Field[]) vector.toArray(new Field[0]);
    }
    
    
    /**
     * <p>For each public static field in the given class
     * of field type int, create a StringIntPair with the
     * name of the field and its int value; then return
     * all such pairs in a StringIntPair array.</p>
     * 
     * <p>In case of an error in extracting the int value,
     * an error message will be appended to the field name
     * before the corresponding StringIntPair is created.</p>
     * 
     * @param type the class type to inspect
     */
    public static StringIntPair[]
        getPublicStaticIntFieldData(Class type)
    {
        Field[] fields = getPublicStaticFields(type, int.class);
        
        int N = fields.length;
        
        StringIntPair[] data = new StringIntPair[N];
        
        for (int i = 0; i < N; i++) {
            String string = fields[i].getName();
            int number = 0;
            
            try {
                number = fields[i].getInt(null);
            }
            catch (IllegalAccessException ex) {
                string += " Error: IllegalAccessException";
            }
            
            data[i] = new StringIntPair(string, number);
        }
        
        return data;
    }
    
    
    /**
     * <p>For each public static field in the given class
     * of field type int, extract the int value; then return
     * all such extracted int values in an int array.</p>
     * 
     * <p>In case of an error in extracting the int value,
     * a value of 0 will be used.</p>
     * 
     * @param type the class type to inspect
     */
    public static int[]
        getPublicStaticIntFieldValues(Class type)
    {
        Field[] fields = getPublicStaticFields(type, int.class);
        
        int N = fields.length;
        
        int[] list = new int[N];
        
        for (int i = 0; i < N; i++) {
            int number = 0;
            
            try {
                number = fields[i].getInt(null);
            }
            catch (IllegalAccessException ex) {}
            
            list[i] = number;
        }
        
        return list;
    }
    
}
