view j2se/test/tools/javac/processing/filer/TestFilerConstraints.java @ 7:807dfe9c366c trunk

[svn] Load openjdk/jdk7/b19 into jdk/trunk.
author xiomara
date Fri, 31 Aug 2007 00:44:13 +0000
parents a4ed3fb96592
children
line wrap: on
line source

/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug 6380018 6453386 6457283
 * @summary Test that the constraints guaranteed by the Filer and maintained
 * @author  Joseph D. Darcy
 * @build TestFilerConstraints
 * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java
 */

import java.util.Set;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import static javax.lang.model.SourceVersion.*;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
import static javax.lang.model.util.ElementFilter.*;
import static javax.tools.Diagnostic.Kind.*;
import static javax.tools.StandardLocation.*;

import java.io.*;
import java.nio.charset.Charset;

/**
 * A processor that verifies the explicit and implicit constraints in
 * the Filer contract are maintained:
 *
 * <blockquote>
 * 
 *  During each run of an annotation processing tool, a file with a
 *  given pathname may be created only once. If that file already
 *  exists before the first attempt to create it, the old contents
 *  will be deleted. Any subsequent attempt to create the same file
 *  during a run will throw a FilerException, as will attempting to
 *  open both a class file and source file for the same type name.
 *
 * </blockquote>
 * 
 * Specific checks will include:
 * 
 * <ul>
 *
 * <li> Source and class files can be written to from either a Writer or an OutputStream.
 *
 * <li> Calling close multiple times does not re-register the file for
 * processing.
 *
 * </ul>
 */
@SupportedAnnotationTypes("*")
public class TestFilerConstraints extends AbstractProcessor {
    private int round = 0;
    private Messager messager;
    private Filer filer;

    private PrintWriter  pw_src1 = null;
    private PrintWriter  pw_src2 = null;
    private OutputStream os_classFile1 = null;
    private      Writer  pw_classFile2 = null;

    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
	round++;

	try {
	    switch(round) {
		// Open two source files
	    case 1:
		pw_src1 = new PrintWriter(filer.createSourceFile("Src1").openWriter());
		pw_src1.println("class Src1 {}");
		pw_src1.close();

		// Hold open across rounds
		pw_src2 = new PrintWriter(new OutputStreamWriter(filer.createSourceFile("Src2").openOutputStream()));
		break;

	    case 2:
		testExpectedType(roundEnv, "Src1");

		// Close Src1 a second time
		pw_src1.close();

		pw_src2.println("class Src2 {}");
		pw_src2.close();
	    
		break;

	    case 3:
		testExpectedType(roundEnv, "Src2");

		// Close Src2 a second time
		pw_src2.close();
	    
		os_classFile1 = filer.createClassFile("ClassFile1").openOutputStream();
		for (int value : classFile1Bytes)
		    os_classFile1.write((byte)value);
		os_classFile1.close();

		break;

	    case 4:
		testExpectedType(roundEnv, "ClassFile1");

		// Close a second time
		os_classFile1.close();

		testReopening();

 		pw_classFile2 = new PrintWriter(filer.createClassFile("ClassFile2",
								      (Element[])null).openWriter());

 		for(int byteVal : classFile2Bytes) {
 		    // int value = (0xff00 & (classFile2Bytes[i]<<8)) | classFile2Bytes[i+1];
 		    // System.out.print(Integer.toHexString(value));
 		    //if ((i % 4) == 0)
		    // System.out.println();
 		    pw_classFile2.write((char) (0xff & byteVal));
 		}
 		pw_classFile2.close();

 		break;



	    case 5:
 		testExpectedType(roundEnv, "ClassFile2");
 		// Close a second time
 		pw_classFile2.close();


 		break;

 	    case 6:
		if (!roundEnv.processingOver() && !roundEnv.errorRaised())
		    throw new RuntimeException("Bad round state: " + roundEnv);
		break;

	    default:
		throw new RuntimeException("Unexpected round number!");
	    }
	} catch (IOException ioe) {
	    throw new RuntimeException(ioe);
	}

        return true;
    }
    
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();
    }

    public void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        messager = processingEnv.getMessager();
        filer    = processingEnv.getFiler();

    }

    /**
     * Test that the single expected expected type, name, is the root
     * element.
     */
    private void testExpectedType(RoundEnvironment roundEnv, String name) {
	if (!roundEnv.getRootElements().isEmpty()) {
	    for(TypeElement type : typesIn(roundEnv.getRootElements())) {
		if (!name.contentEquals(type.getSimpleName()))
		    throw new RuntimeException("Unexpected type " +  type.getSimpleName());
	    } 
	} else
	    throw new RuntimeException("Unexpected empty root elements.");
    }

    private void testReopening() throws IOException {
	String[] names = {"Src1", "Src2", "ClassFile1"};
	for (String name : names) {
	    try {
		filer.createSourceFile(name);
		throw new RuntimeException("Opened a source file for type " + name);
	    } catch (FilerException fe) {;}

	    try {
		filer.createClassFile(name);
		throw new RuntimeException("Opened a class file for type " + name);
	    } catch (FilerException fe) {;}
	}

	// Try to open a resource over a source file
	try {
	    filer.createResource(SOURCE_OUTPUT, "", "Src1.java");
	    throw new RuntimeException("Opened a text file over Src1.java!");
	} catch (FilerException fe) {;}
	
	// Try to open a resource over a class file
	try {
	    filer.createResource(CLASS_OUTPUT, "", "ClassFile1.class");
	    throw new RuntimeException("Opened a text file over Src1.java!");
	} catch (FilerException fe) {;}
	
    }

    private int[] classFile1Bytes = 
    {202, 254, 186, 190,   0,   0,   0,  50,
       0,  13,  10,   0,   3,   0,  10,   7,
       0,  11,   7,   0,  12,   1,   0,   6,
      60, 105, 110, 105, 116,  62,   1,   0,
       3,  40,  41,  86,   1,   0,   4,  67,
     111, 100, 101,   1,   0,  15,  76, 105,
     110, 101,  78, 117, 109,  98, 101, 114,
      84,  97,  98, 108, 101,   1,   0,  10,
      83, 111, 117, 114,  99, 101,  70, 105,
     108, 101,   1,   0,  15,  67, 108,  97,
     115, 115,  70, 105, 108, 101,  49,  46,
     106,  97, 118,  97,  12,   0,   4,   0,
       5,   1,   0,  10,  67, 108,  97, 115,
     115,  70, 105, 108, 101,  49,   1,   0,
      16, 106,  97, 118,  97,  47, 108,  97,
     110, 103,  47,  79,  98, 106, 101,  99,
     116,   0,  33,   0,   2,   0,   3,   0,
       0,   0,   0,   0,   1,   0,   1,   0,
       4,   0,   5,   0,   1,   0,   6,   0,
       0,   0,  29,   0,   1,   0,   1,   0,
       0,   0,   5,  42, 183,   0,   1, 177,
       0,   0,   0,   1,   0,   7,   0,   0,
       0,   6,   0,   1,   0,   0,   0,   1,
       0,   1,   0,   8,   0,   0,   0,   2,
       0,   9,};

    private int[] classFile2Bytes = 
    {202, 254, 186, 190,   0,   0,   0,  50,
       0,  13,  10,   0,   3,   0,  10,   7,
       0,  11,   7,   0,  12,   1,   0,   6,
      60, 105, 110, 105, 116,  62,   1,   0,
       3,  40,  41,  86,   1,   0,   4,  67,
     111, 100, 101,   1,   0,  15,  76, 105,
     110, 101,  78, 117, 109,  98, 101, 114,
      84,  97,  98, 108, 101,   1,   0,  10,
      83, 111, 117, 114,  99, 101,  70, 105,
     108, 101,   1,   0,  15,  67, 108,  97,
     115, 115,  70, 105, 108, 101,  50,  46,
     106,  97, 118,  97,  12,   0,   4,   0,
       5,   1,   0,  10,  67, 108,  97, 115,
     115,  70, 105, 108, 101,  50,   1,   0,
      16, 106,  97, 118,  97,  47, 108,  97,
     110, 103,  47,  79,  98, 106, 101,  99,
     116,   0,  33,   0,   2,   0,   3,   0,
       0,   0,   0,   0,   1,   0,   1,   0,
       4,   0,   5,   0,   1,   0,   6,   0,
       0,   0,  29,   0,   1,   0,   1,   0,
       0,   0,   5,  42, 183,   0,   1, 177,
       0,   0,   0,   1,   0,   7,   0,   0,
       0,   6,   0,   1,   0,   0,   0,   1,
       0,   1,   0,   8,   0,   0,   0,   2,
       0,   9,};
}