/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.test.mappingsmodel.spi.meta.classfile; import java.io.File; import java.io.FileWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClass; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassDescription; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassRepository; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassRepositoryFactory; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalField; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.classfile.CFExternalClassRepositoryFactory; import org.eclipse.persistence.tools.workbench.test.mappingsmodel.spi.meta.ExternalClassRepositoryTests; import org.eclipse.persistence.tools.workbench.test.utility.JavaTools; import org.eclipse.persistence.tools.workbench.utility.ClassTools; import org.eclipse.persistence.tools.workbench.utility.Classpath; import org.eclipse.persistence.tools.workbench.utility.io.FileTools; import org.eclipse.persistence.tools.workbench.utility.io.IndentingPrintWriter; public class CFExternalClassRepositoryTests extends ExternalClassRepositoryTests { public static Test suite() { return new TestSuite(CFExternalClassRepositoryTests.class); } public CFExternalClassRepositoryTests(String name) { super(name); } protected ExternalClassRepositoryFactory buildFactory() { return CFExternalClassRepositoryFactory.instance(); } protected ExternalClassRepository systemClasspathRepository() { return this.factory.buildClassRepository(this.buildSystemClasspath()); } protected ExternalClassRepository systemRepositoryFor(ExternalClassRepository repository) { return repository; } protected void verifyArrayTypesContains(Map arrayTypes, Class arrayType) { assertTrue(arrayTypes.containsKey(arrayType.getName())); } protected ExternalClassRepository buildExternalClassRepository(File[] classpath) { File[] systemClasspath = AllModelSPIMetaClassFileTests.buildMinimumSystemClasspath(); File[] combinedClasspath = new File[systemClasspath.length + classpath.length]; System.arraycopy(systemClasspath, 0, combinedClasspath, 0, systemClasspath.length); System.arraycopy(classpath, 0, combinedClasspath, systemClasspath.length, classpath.length); return this.factory.buildClassRepository(combinedClasspath); } private File[] buildSystemClasspath() { List systemClasspath = new ArrayList(); Classpath cp = Classpath.completeClasspath(); Classpath.Entry[] entries = cp.getEntries(); int len = entries.length; for (int i = 0; i < len; i++) { systemClasspath.add(entries[i].file()); } systemClasspath.add(new File(Classpath.locationFor(this.getClass()))); return (File[]) systemClasspath.toArray(new File[systemClasspath.size()]); } public void test4309188() throws Exception { File tempDir = this.buildTempDir(); // first make sure we can load the classes... ExternalClassRepository repos = this.buildExternalClassRepository(new File[] {tempDir}); ExternalClassDescription exClassDescription1 = repos.getClassDescription("foo.bar.TestClass1"); ExternalClass exClass1 = exClassDescription1.getExternalClass(); assertEquals("foo.bar.TestClass1", exClass1.getName()); ExternalClassDescription exClassDescription2 = repos.getClassDescription("foo.bar.TestClass2"); ExternalClass exClass2 = exClassDescription2.getExternalClass(); assertEquals("foo.bar.TestClass2", exClass2.getName()); // ...then delete TestClass1 File classFile1 = new File(new File(new File(tempDir, "foo"), "bar"), "TestClass1.class"); assertTrue(classFile1.delete()); repos = this.buildExternalClassRepository(new File[] {tempDir}); exClassDescription2 = repos.getClassDescription("foo.bar.TestClass2"); exClass2 = exClassDescription2.getExternalClass(); ExternalField[] fields2 = exClass2.getDeclaredFields(); assertEquals(1, fields2.length); assertEquals("testClass1", fields2[0].getName()); // this will trigger the creation of "stub" TestClass1, since TestClass1 is not on the classpath any more assertEquals("foo.bar.TestClass1", fields2[0].getType().getName()); exClassDescription1 = repos.getClassDescription("foo.bar.TestClass1"); assertNull(exClassDescription1); // this next line is what used to throw an IllegalStateException in CFExternalClassDescription#buildExternalClass() // exClass1 = exClassDescription1.getExternalClass(); this.deleteDir(tempDir); } private File buildTempDir() throws Exception { File tempDir = FileTools.emptyTemporaryDirectory(ClassTools.shortClassNameForObject(this) + "." + this.getName()); File fooDir = new File(tempDir, "foo"); fooDir.mkdir(); File barDir = new File(fooDir, "bar"); barDir.mkdir(); this.buildClassFile1(tempDir); this.buildClassFile2(tempDir); return tempDir; } private void buildClassFile1(File tempDir) throws Exception { File sourceFile = new File(new File(new File(tempDir, "foo"), "bar"), "TestClass1.java"); IndentingPrintWriter pw = new IndentingPrintWriter(new FileWriter(sourceFile)); this.printSource1On(pw); pw.close(); JavaTools.compile(sourceFile, tempDir.getAbsolutePath()); } private void printSource1On(IndentingPrintWriter pw) { pw.println("package foo.bar;"); pw.println("public class TestClass1 {"); pw.indent(); pw.println("public java.lang.String string;"); pw.println("public TestClass1() {super();}"); pw.undent(); pw.println("}"); } private void buildClassFile2(File tempDir) throws Exception { File sourceFile = new File(new File(new File(tempDir, "foo"), "bar"), "TestClass2.java"); IndentingPrintWriter pw = new IndentingPrintWriter(new FileWriter(sourceFile)); this.printSource2On(pw); pw.close(); JavaTools.compile(sourceFile, tempDir.getAbsolutePath()); } private void printSource2On(IndentingPrintWriter pw) { pw.println("package foo.bar;"); pw.println("public class TestClass2 {"); pw.indent(); pw.println("public foo.bar.TestClass1 testClass1;"); pw.println("public TestClass2() {super();}"); pw.undent(); pw.println("}"); } private void deleteDir(File dir) { FileTools.deleteDirectory(dir); } }