/******************************************************************************* * Copyright (c) 1998, 2016 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.mappingsplugin; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Vector; import java.util.prefs.Preferences; import org.eclipse.persistence.indirection.ValueHolderInterface; import org.eclipse.persistence.sessions.Project; import org.eclipse.persistence.tools.workbench.framework.Application; import org.eclipse.persistence.tools.workbench.framework.NodeManager; import org.eclipse.persistence.tools.workbench.framework.context.ApplicationContext; import org.eclipse.persistence.tools.workbench.framework.help.HelpManager; import org.eclipse.persistence.tools.workbench.framework.resources.DefaultResourceRepository; import org.eclipse.persistence.tools.workbench.framework.resources.IconResourceFileNameMap; import org.eclipse.persistence.tools.workbench.framework.resources.ResourceRepository; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWColumn; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWDatabase; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWLoginSpec; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWReference; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWTable; import org.eclipse.persistence.tools.workbench.mappingsmodel.generation.MWDescriptorGenerator; import org.eclipse.persistence.tools.workbench.mappingsmodel.generation.MWRelationshipHolder; import org.eclipse.persistence.tools.workbench.mappingsmodel.project.relational.MWRelationalProject; import org.eclipse.persistence.tools.workbench.mappingsplugin.MappingsPluginResourceBundle; import org.eclipse.persistence.tools.workbench.mappingsplugin.sourcegen.SourceCodeGenerator; import org.eclipse.persistence.tools.workbench.platformsmodel.DatabasePlatform; import org.eclipse.persistence.tools.workbench.test.mappingsmodel.MappingsModelTestTools; import org.eclipse.persistence.tools.workbench.test.models.projects.TestDatabases; import org.eclipse.persistence.tools.workbench.test.utility.JavaTools; import org.eclipse.persistence.tools.workbench.test.utility.TestTools; import org.eclipse.persistence.tools.workbench.uitools.CancelException; import org.eclipse.persistence.tools.workbench.utility.ClassTools; import org.eclipse.persistence.tools.workbench.utility.Classpath; import org.eclipse.persistence.tools.workbench.utility.CollectionTools; import org.eclipse.persistence.tools.workbench.utility.io.FileTools; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class ExportModelJavaSourceTests extends TestCase { private MWRelationalProject project; private File tempDirectory; private String clientClassShortName; public static Test suite() { TestTools.setUpJUnitThreadContextClassLoader(); return new TestSuite(ExportModelJavaSourceTests.class); } public ExportModelJavaSourceTests(String name) { super(name); } // **************** test set up, tear down stuff ************************** @Override protected void setUp() throws Exception { super.setUp(); this.tempDirectory = FileTools.emptyTemporaryDirectory(ClassTools.shortClassNameForObject(this) + "." + this.getName()); this.project = this.buildProject(); } @Override protected void tearDown() throws Exception { TestTools.clear(this); super.tearDown(); } /** * builds a project with tables only */ private MWRelationalProject buildProject() { MWRelationalProject result = new MWRelationalProject(ClassTools.shortClassNameForObject(this), MappingsModelTestTools.buildSPIManager(), null); // database MWDatabase database = result.getDatabase(); TestDatabases.configureMySQLDatabase(database); DatabasePlatform platform = database.getDatabasePlatform(); // employee table MWTable employeeTable = database.addTable("employee"); MWColumn empIdField = employeeTable.addColumn("id"); empIdField.setDatabaseType(platform.databaseTypeNamed("integer")); empIdField.setPrimaryKey(true); MWColumn nameField = employeeTable.addColumn("name"); nameField.setDatabaseType(platform.databaseTypeNamed("varchar")); // phone number table MWTable phoneNumberTable = database.addTable("phone_number"); MWColumn phoneIdField = phoneNumberTable.addColumn("id"); phoneIdField.setDatabaseType(platform.databaseTypeNamed("integer")); phoneIdField.setPrimaryKey(true); MWColumn phoneEmpIdField = phoneNumberTable.addColumn("emp_id"); phoneEmpIdField.setDatabaseType(platform.databaseTypeNamed("integer")); MWColumn numField = phoneNumberTable.addColumn("num"); numField.setDatabaseType(platform.databaseTypeNamed("varchar")); // phone number -> employee reference MWReference phoneNumberEmployeeReference = phoneNumberTable.addReference("phone_number_employee", employeeTable); phoneNumberEmployeeReference.addColumnPair(phoneEmpIdField, empIdField); return result; } private String getPackageName() { return "foo"; } private String getClientClassShortName() { return this.clientClassShortName; } private String getClientClassName() { return getPackageName() + "." + getClientClassShortName(); } // **************** actual test methods *********************************** public void testGenerateEndToEndWithDirectFieldAccessing() throws Exception { this.clientClassShortName = "DirectAccessingEndToEndClient"; internalTestGenerateEndToEnd(false); } public void testGenerateEndToEndWithMethodAccessing() throws Exception { this.clientClassShortName = "MethodAccessingEndToEndClient"; internalTestGenerateEndToEnd(true); } // **************** guts of the tests ************************************* private void internalTestGenerateEndToEnd(boolean generateMethods) throws Exception { generateDescriptors(generateMethods); generateSourceCode(); compileSourceCode(); generateAndCompileProjectCode(); setUpDatabase(); exerciseClient(); } // **************** generating the descriptors **************************** private void generateDescriptors(boolean generateMethods) { MWDescriptorGenerator generator = new MWDescriptorGenerator(); generator.setGenerateBidirectionalRelationships(false); generator.setGenerateEjbs(false); generator.setGenerateMethodAccessors(generateMethods); generator.setGenerateLocalInterfaces(false); generator.setGenerateRemoteInterfaces(false); generator.setPackageName(getPackageName()); generator.setProject(this.project); generator.setRelationshipsToCreate(relationshipsToCreate()); generator.setTables(CollectionTools.collection(this.project.getDatabase().tables())); generator.generateClassesAndDescriptors(); } private Collection relationshipsToCreate() { Collection relationships = new Vector(); MWReference phoneNumberToEmployeeRef = this.project.getDatabase().tableNamed("phone_number").referenceNamed("phone_number_employee"); MWRelationshipHolder phoneNumberToEmployee = new MWRelationshipHolder(phoneNumberToEmployeeRef, false); phoneNumberToEmployee.setOneToOne(); relationships.add(phoneNumberToEmployee); MWRelationshipHolder employeeToPhoneNumbers = new MWRelationshipHolder(phoneNumberToEmployeeRef, true); employeeToPhoneNumbers.setOneToMany(); relationships.add(employeeToPhoneNumbers); return relationships; } // **************** generating the source code **************************** private void generateSourceCode() { SourceCodeGenerator generator = new SourceCodeGenerator(buildApplicationContext()); generator.setOverwriteFiles(true); try { generator.generateSourceCode(this.project, CollectionTools.collection(this.project.descriptors()), this.tempDirectory); } catch (CancelException e) { throw new RuntimeException(e); } } private ApplicationContext buildApplicationContext() { return new ApplicationContext() { @Override public Application getApplication() { return new Application() { @Override public String getFullProductName() { return null; } @Override public String getProductName() { return null; } @Override public String getShortProductName() { return null; } @Override public String getVersionNumber() { return null; } @Override public String getReleaseDesignation() { return null; } @Override public String getFullProductNameAndVersionNumber() { return null; } @Override public String getBuildNumber() { return null; } @Override public boolean isDevelopmentMode() { return false; } @Override public boolean isFirstExecution() { return false; } }; } @Override public Preferences getPreferences() { return null; } @Override public ResourceRepository getResourceRepository() { return new DefaultResourceRepository(MappingsPluginResourceBundle.class); } @Override public NodeManager getNodeManager() { return null; } @Override public HelpManager getHelpManager() { return null; } @Override public ApplicationContext buildRedirectedPreferencesContext(String path) { return null; } @Override public ApplicationContext buildExpandedResourceRepositoryContext(Class resourceBundleClass, IconResourceFileNameMap iconResourceFileNameMap) { return null; } @Override public ApplicationContext buildExpandedResourceRepositoryContext(IconResourceFileNameMap iconResourceFileNameMap) { return null; } @Override public ApplicationContext buildExpandedResourceRepositoryContext(Class resourceBundleClass) { return null; } }; } // **************** compiling the source code ***************************** private void compileSourceCode() throws Exception { // the code includes references to ValueHolderInterface JavaTools.compile(FileTools.filesInTree(this.tempDirectory), Classpath.locationFor(ValueHolderInterface.class)); } // **************** generating and compiling the project source code ****** private void generateAndCompileProjectCode() throws Exception { String projectClassShortName = "EndToEndProject"; this.project.setProjectSourceClassName(getPackageName() + "." + projectClassShortName); this.project.setProjectSourceDirectoryName(this.tempDirectory.getAbsolutePath()); this.project.getRepository().addClasspathEntry(this.tempDirectory.getAbsolutePath()); this.project.exportProjectSource(); copyClientFileToTempDir(); // easier to recompile model code than work them into the classpath JavaTools.compile(FileTools.filesInTree(this.tempDirectory), Classpath.locationFor(Project.class)); } private void copyClientFileToTempDir() throws Exception { File clientFile = FileTools.resourceFile("/export/" + getClientClassShortName() + ".java"); FileTools.copyToDirectory(clientFile, new File(this.tempDirectory, getPackageName())); } // **************** exercising the client ********************************* private void setUpDatabase() throws Exception { this.project.getDatabase().login(); this.project.getDatabase().generateTables(); this.project.getDatabase().logout(); } private void exerciseClient() throws Exception { // all we should need on the classpath is the domain classes, toplink, and the db driver List classpathEntries = new ArrayList(); classpathEntries.add(this.tempDirectory.getAbsolutePath()); classpathEntries.add(Classpath.locationFor(Project.class)); MWLoginSpec loginSpec = this.project.getDatabase().getDeploymentLoginSpec(); classpathEntries.add(Classpath.locationFor(Class.forName(loginSpec.getDriverClassName()))); for (Iterator stream = loginSpec.fullyQualifiedDriverClasspathFiles(); stream.hasNext(); ) { File file = (File) stream.next(); classpathEntries.add(file.getAbsolutePath()); } Classpath classpath = new Classpath(classpathEntries); // this *should* throw an exception if there are any problems JavaTools.java(this.getClientClassName(), classpath.path()); } }