/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
/*
 * Contributor(s): Thomas Ball
 */

import org.netbeans.modules.classfile.*;
import java.io.*;
import java.util.*;

/**
 * PrintClass:  write a class as a println statement.
 *
 * @author Thomas Ball
 */
public class PrintClass {
    String thisClass;

    PrintClass(String spec) {
        thisClass = spec;
    }

    void print(PrintStream out) throws IOException {
        ClassName cn = ClassName.getClassName(thisClass.replace('.', '/'));
	InputStream is = findClassStream(cn.getType());
	if (is == null) {
	    System.err.println("couldn't find class: " + 
			       cn.getExternalName());
	    return;
	}
	ClassFile cfile = new ClassFile(is);
        out.println(cfile);
    }

    private InputStream findClassStream(String className) {
        InputStream is = 
            ClassLoader.getSystemClassLoader().getResourceAsStream(className + ".class");
        return is;
    }

    /**
     * An error routine which displays the command line usage
     * before exiting.
     */
    public static void usage() {
        System.err.println(
            "usage:  java PrintClass <class> [ <class> ...]");
        System.exit(1);
    }

    public static void main(String[] args) {
        if (args.length == 0)
            usage();

        for (int i = 0; i < args.length; i++) {
            if (args[i].charAt(0) == '-')
                usage();
            else {
                try {
                    PrintClass pc = new PrintClass(args[i]);
                    pc.print(System.out);
                } catch (IOException e) {
                    System.err.println("error accessing \"" + args[i] + 
                                       "\": " + e.toString());
                }
            }
        }
    }
}
