/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/util/org/apache/slide/util/Misc.java,v 1.3 2004/07/30 06:52:17 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:17 $
 *
 * ====================================================================
 *
 * Copyright 1999-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.slide.util;


import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

/**
 ** Class to collect useful algorithms used within other classes.
 **
 ** @author michael.hartmeier@softwareag.com
 ** @version $Revision: 1.3 $
 */
public class Misc {
    /**
     ** @return absolute resource name
     **/
    public static String getPackageResourceName(Class clazz) {
        String name;
        int idx;
        
        name = clazz.getName();
        idx = name.lastIndexOf('.');
        if (idx == -1) {
            throw new XAssertionFailed(name);
        }
        name = name.substring(0, idx);
        return "/" + name.replace('.', '/');
    }
    
    public static boolean eq(Object a, Object b) {
        return (a == null)? b == null : a.equals(b);
    }
    
    /**
     ** Returns the file of a certain class.
     **
     ** @param c the source class
     **
     ** @return the physical file refering to the class
     **/
    public static File locateClasspathItem(Class c) {
        String classname;
        URL url;
        File file;
        
        classname = "/" + c.getName().replace('.', '/') + ".class";
        url = c.getResource(classname);
        file = locateClasspathItem(url, classname);
        if (!file.exists()) {
            throw new XAssertionFailed("no such file or directory: " + file);
        }
        return file;
    }
    
    /**
     ** Returns the file of a certain class at a special location. e.g. jar files
     **
     ** @param url the destination path
     ** @param classname  absolute resource name **
     **
     ** @return the physical file refering to the class
     **/
    public static File locateClasspathItem(URL url, String classname) {
        // Caution: don'T user File.isFile or File.isDirectory here -- this method is called
        // from test cases
        
        String filename;
        File file;
        String protocol;
        int idx;
        URL suburl;
        
        if (!classname.startsWith("/")) {
            throw new XAssertionFailed(classname);
        }
        protocol = url.getProtocol();
        if ("file".equals(protocol)) {
            file = Files.getFile(url);
            filename = file.getPath();
            if (!filename.endsWith(classname.replace('/', File.separatorChar))) {
                throw new XAssertionFailed("classname not found in file url: " + filename + " " + classname);
            }
            file = new File(filename.substring(0, filename.length() - classname.length()));
        } else if ("jar".equals(protocol)) {
            filename = url.getFile();
            idx = filename.indexOf('!');
            if (idx == -1) {
                throw new XAssertionFailed("! not found: " + filename);
            }
            try {
                suburl = new URL(filename.substring(0, idx));
            } catch (MalformedURLException e) {
                throw new XAssertionFailed("invalid suburl in " + filename, e);
            }
            if (!"file".equals(suburl.getProtocol())) {
                throw new XAssertionFailed("unsupported sub protocol:" + suburl.toString());
            }
            file = Files.getFile(suburl);
        } else {
            throw new XAssertionFailed("protocol not supported: " + protocol);
        }
        if (!file.isAbsolute()) {
            throw new XAssertionFailed("absolute file name expected: " + filename);
        }
        return file;
    }
    
    public static String getXercesName() {
        // no hard-writed references to the version class because it might be unavailable
        Class c;
        Method m;
        Object obj;
        
        try {
            c = Class.forName("org.apache.xerces.impl.Version");
            m = c.getDeclaredMethod("getVersion", new Class[] {});
            if (Modifier.isStatic(m.getModifiers())) {
                // Xerces 2.2.1
                obj = null;
            } else {
                // Xerces 2.1
                obj = c.newInstance();
            }
            return (String) m.invoke(obj, new Object[] {});
        } catch (Exception e) {
            return "unkown (" + e.getMessage() + ")";
        }
    }
     
    //--
    
    public static List lst(Object obj) {
        return Arrays.asList(new Object[] { obj });
    }
    public static List lst(Object obj1, Object obj2) {
        return Arrays.asList(new Object[] { obj1, obj2 });
    }
    public static List lst(Object obj1, Object obj2, Object obj3) {
        return Arrays.asList(new Object[] { obj1, obj2, obj3 });
    }
    public static List lst(Object obj1, Object obj2, Object obj3, Object obj4) {
        return Arrays.asList(new Object[] { obj1, obj2, obj3, obj4 });
    }
}

