/******************************************************************************* * Copyright (c) 2005, 2007 BEA Systems, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * jgarms@bea.com - initial API and implementation * *******************************************************************************/ package org.eclipse.jdt.apt.tests; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.apt.core.internal.AptPlugin; import org.eclipse.jdt.apt.core.internal.FactoryPluginManager; import org.eclipse.jdt.apt.core.internal.generatedfile.GeneratedSourceFolderManager; import org.eclipse.jdt.apt.core.internal.util.FactoryContainer; import org.eclipse.jdt.apt.core.internal.util.FactoryPath; import org.eclipse.jdt.apt.core.internal.util.FactoryPathUtil; import org.eclipse.jdt.apt.core.internal.util.FactoryContainer.FactoryType; import org.eclipse.jdt.apt.core.util.AptConfig; import org.eclipse.jdt.apt.core.util.AptPreferenceConstants; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.tests.util.Util; public class PreferencesTests extends APTTestBase { public PreferencesTests(final String name) { super( name ); } public static Test suite() { return new TestSuite( PreferencesTests.class ); } public void testFactoryPathEncodingAndDecoding() throws Exception { //encode Map<FactoryContainer, FactoryPath.Attributes> factories = new LinkedHashMap<FactoryContainer, FactoryPath.Attributes>(); FactoryContainer jarFactory1 = FactoryPathUtil.newExtJarFactoryContainer(new File(JAR_PATH_1)); //$NON-NLS-1$ FactoryPath.Attributes jarFPA1 = new FactoryPath.Attributes(true, false); FactoryContainer jarFactory2 = FactoryPathUtil.newExtJarFactoryContainer(new File(JAR_PATH_2)); //$NON-NLS-1$ FactoryPath.Attributes jarFPA2 = new FactoryPath.Attributes(true, true); FactoryContainer pluginFactory = FactoryPluginManager.getPluginFactoryContainer("org.eclipse.jdt.apt.tests"); //$NON-NLS-1$ FactoryPath.Attributes pluginFPA = new FactoryPath.Attributes(false, false); factories.put(jarFactory1, jarFPA1); factories.put(jarFactory2, jarFPA2); factories.put(pluginFactory, pluginFPA); String xml = FactoryPathUtil.encodeFactoryPath(factories); assertEquals(serializedFactories, xml); // decode factories = FactoryPathUtil.decodeFactoryPath(xml); assertEquals(3, factories.size()); int index=0; for (Map.Entry<FactoryContainer, FactoryPath.Attributes> entry : factories.entrySet()) { FactoryContainer container = entry.getKey(); switch (index) { case 0: // jar1 assertEquals(FactoryType.EXTJAR, container.getType()); assertTrue(entry.getValue().isEnabled()); assertFalse(entry.getValue().runInBatchMode()); break; case 1: // jar2 assertEquals(FactoryType.EXTJAR, container.getType()); assertTrue(entry.getValue().isEnabled()); assertTrue(entry.getValue().runInBatchMode()); break; case 2: // plugin assertEquals(FactoryType.PLUGIN, container.getType()); assertFalse(entry.getValue().isEnabled()); assertEquals("org.eclipse.jdt.apt.tests", container.getId()); //$NON-NLS-1$ break; default: fail("FactoryPath had an unexpected number of entries: " + (index + 1)); } index++; } } // Need to use temp files to get path to external jars. // Platform differences prevent us from hard-coding a string here private static final String JAR_PATH_1; private static final String JAR_PATH_2; static { File jar1 = null; File jar2 = null; try { jar1 = File.createTempFile("test1", "jar"); jar2 = File.createTempFile("test2", "jar"); JAR_PATH_1 = jar1.getAbsolutePath(); JAR_PATH_2 = jar2.getAbsolutePath(); } catch (IOException ioe) { throw new RuntimeException("Could not create temp jar files", ioe); } finally { if (jar1 != null) jar1.delete(); if (jar2 != null) jar2.delete(); } } private static final String serializedFactories = "<factorypath>\n" + " <factorypathentry kind=\"EXTJAR\" id=\"" + JAR_PATH_1 + "\" enabled=\"true\" runInBatchMode=\"false\"/>\n" + " <factorypathentry kind=\"EXTJAR\" id=\"" + JAR_PATH_2 + "\" enabled=\"true\" runInBatchMode=\"true\"/>\n" + " <factorypathentry kind=\"PLUGIN\" id=\"org.eclipse.jdt.apt.tests\" enabled=\"false\" runInBatchMode=\"false\"/>\n" + "</factorypath>\n"; /** * Test the config API for settings other than factory path * @throws Exception */ public void testSimpleConfigApi() throws Exception { IJavaProject jproj = env.getJavaProject( getProjectName() ); // aptEnabled AptConfig.setEnabled(jproj, false); assertFalse(AptConfig.isEnabled(jproj)); assertFalse(AptConfig.isEnabled(null)); AptConfig.setEnabled(jproj, true); assertTrue(AptConfig.isEnabled(jproj)); assertFalse(AptConfig.isEnabled(null)); // processorOptions Map<String, String> wkspOpts = new HashMap<String, String>(3); wkspOpts.put("b", "bVal"); wkspOpts.put("another option", "and\\more \"punctuation!\""); AptConfig.setProcessorOptions(wkspOpts, null); Map<String, String> retrievedWkspOpts = AptConfig.getRawProcessorOptions(null); assertTrue("getRawProcessorOptions() should return the values set in setProcessorOptions()", wkspOpts.equals(retrievedWkspOpts)); Map<String, String> projOpts = new HashMap<String, String>(3); projOpts.put("a", "aVal"); projOpts.put("with spaces", "value also has spaces"); projOpts.put("foo", "bar"); AptConfig.setProcessorOptions(projOpts, jproj); Map<String, String> retrievedProjOpts = AptConfig.getRawProcessorOptions(jproj); assertTrue("getRawProcessorOptions() should return the values set in setProcessorOptions()", projOpts.equals(retrievedProjOpts)); wkspOpts.clear(); wkspOpts.put("noodle", "nubble"); wkspOpts.put("spoo/mack", "wumpus"); AptConfig.setProcessorOptions(wkspOpts, null); retrievedWkspOpts = AptConfig.getRawProcessorOptions(null); assertTrue("getRawProcessorOptions() should return the values set in setProcessorOptions()", wkspOpts.equals(retrievedWkspOpts)); projOpts.clear(); projOpts.put("smurf", "more smurfs\\=bad"); projOpts.put("baz/quack", "quux"); AptConfig.setProcessorOptions(projOpts, jproj); retrievedProjOpts = AptConfig.getRawProcessorOptions(jproj); assertTrue("getRawProcessorOptions() should return the values set in setProcessorOptions()", projOpts.equals(retrievedProjOpts)); AptConfig.addProcessorOption(jproj, "foo", "bar"); AptConfig.addProcessorOption(jproj, "space", "\"text with spaces\""); AptConfig.addProcessorOption(jproj, "quux", null); AptConfig.addProcessorOption(jproj, "quux", null); // adding twice should have no effect Map<String, String> options = AptConfig.getProcessorOptions(jproj); String val = options.get("foo"); assertEquals(val, "bar"); val = options.get("quux"); assertNull(val); val = options.get("space"); assertEquals(val, "\"text with spaces\""); AptConfig.removeProcessorOption(jproj, "foo"); options = AptConfig.getProcessorOptions(jproj); assertFalse(options.containsKey("foo")); assertTrue(options.containsKey("quux")); AptConfig.removeProcessorOption(jproj, "quux"); AptConfig.removeProcessorOption(jproj, "anOptionThatDoesn'tExist"); AptConfig.addProcessorOption(null, "workspace option", "corresponding value"); AptConfig.addProcessorOption(null, "foo", "whatever"); AptConfig.removeProcessorOption(null, "foo"); options = AptConfig.getProcessorOptions(null); assertFalse(options.containsKey("foo")); assertTrue(options.containsKey("workspace option")); AptConfig.removeProcessorOption(null, "workspace option"); } /** * Test the config API for automatically generated options. */ public void testAutomaticOptions() throws Exception { IJavaProject jproj = env.getJavaProject( getProjectName() ); Map<String,String> options = AptConfig.getProcessorOptions(jproj); String classpath = options.get("-classpath"); assertNotNull(classpath); assertTrue(classpath.length() > 0); String sourcepath = options.get("-sourcepath"); assertNotNull(sourcepath); assertTrue(sourcepath.length() > 0); String target = options.get("-target"); assertEquals(target, "1.5"); String source = options.get("-source"); assertEquals(source, "1.5"); String bindir = options.get("-d"); assertNotNull(bindir); assertTrue(bindir.length() > 0); String gensrcdirAuto = options.get("-s"); assertNotNull(gensrcdirAuto); assertTrue(gensrcdirAuto.length() > 0); } public void testGenSrcDir() throws Exception { IJavaProject jproj = env.getJavaProject( getProjectName() ); String genSrcDir = AptConfig.getGenSrcDir(jproj); assertEquals(AptPreferenceConstants.DEFAULT_GENERATED_SOURCE_FOLDER_NAME, genSrcDir); final String newDir = "gen/src"; AptConfig.setGenSrcDir(jproj, newDir); genSrcDir = AptConfig.getGenSrcDir(jproj); assertEquals(newDir, genSrcDir); } /** * Test a series of configuration and make sure the GeneratedFileManager and * the classpath reflecting the setup. Configuration setting includes * enabling and disabling apt and configure the generated source folder * with and without apt enabled. * * See comments in method body for detail testing scenarios * @throws Exception */ public void testConfigGenSrcDir() throws Exception { final String projectName = "ConfigTestProj"; IPath projectPath = env.addProject( projectName, "1.5" ); env.addExternalJars( projectPath, Util.getJavaClassLibs() ); final IJavaProject javaProj = env.getJavaProject(projectName); // APT is not enabled boolean aptEnabled = AptConfig.isEnabled(javaProj); // test 1: make sure apt is disabled by default assertEquals(false, aptEnabled); final GeneratedSourceFolderManager gsfm = AptPlugin.getAptProject(javaProj).getGeneratedSourceFolderManager(); IFolder srcFolder = gsfm.getFolder(); String folderName = srcFolder.getProjectRelativePath().toOSString(); // test 2: apt is disabled, then folder should not exists assertEquals(srcFolder.exists(), false); // test 3: folder name has not been configured, then it should be the default. // folder name should be the default name. assertEquals(folderName, AptPreferenceConstants.DEFAULT_GENERATED_SOURCE_FOLDER_NAME); // set folder name while apt is disabled String newName = ".gensrcdir"; AptConfig.setGenSrcDir(javaProj, newName); srcFolder = gsfm.getFolder(); folderName = srcFolder.getProjectRelativePath().toOSString(); // test 4: apt still disabled but folder name changed, make sure the folder is not on disk. assertEquals(false, srcFolder.exists()); // test 5: make sure we got the new name assertEquals(newName, folderName); // test 6: make sure the source folder is not on the classpath. assertEquals( false, isOnClasspath(javaProj, srcFolder.getFullPath()) ); // enable apt AptConfig.setEnabled(javaProj, true); aptEnabled = AptConfig.isEnabled(javaProj); // test 7: make sure it's enabled after we called the API to enable it. assertEquals(true, aptEnabled); srcFolder = gsfm.getFolder(); folderName = srcFolder.getProjectRelativePath().toOSString(); // test 8: apt enabled, the source folder should be on disk assertEquals(true, srcFolder.exists()); // test 9: make sure the name matches assertEquals(newName, folderName); // test 10: apt is enabled, folder must be on classpath. assertEquals( true, isOnClasspath(javaProj, srcFolder.getFullPath()) ); // now disable apt. AptConfig.setEnabled(javaProj, false); aptEnabled = AptConfig.isEnabled(javaProj); // test 11: make sure it's disabled. assertEquals(false, aptEnabled); srcFolder = gsfm.getFolder(); folderName = srcFolder.getProjectRelativePath().toOSString(); // test 12: make sure we deleted the source folder when we disable apt assertEquals(false, srcFolder.exists()); // test 13: make sure we didn't overwrite the configure folder name assertEquals(newName, folderName); // test 14: make sure we cleaned up the classpath. assertEquals( false, isOnClasspath(javaProj, srcFolder.getFullPath()) ); } private boolean isOnClasspath(IJavaProject javaProj, IPath path) throws JavaModelException { final IClasspathEntry[] cp = javaProj.getRawClasspath(); for (int i = 0; i < cp.length; i++) { if (cp[i].getPath().equals( path )) { return true; } } return false; } }