/*******************************************************************************
* 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.mappingsplugin.sourcegen;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.prefs.Preferences;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContext;
import org.eclipse.persistence.tools.workbench.framework.resources.ResourceRepository;
import org.eclipse.persistence.tools.workbench.framework.ui.dialog.ExceptionDialog;
import org.eclipse.persistence.tools.workbench.framework.uitools.FileChooser;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWDescriptor;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWMappingDescriptor;
import org.eclipse.persistence.tools.workbench.mappingsmodel.project.MWProject;
import org.eclipse.persistence.tools.workbench.mappingsplugin.MappingsPlugin;
import org.eclipse.persistence.tools.workbench.uitools.CancelException;
public final class ModelSourceGenerationCoordinator
implements SourceCodeGenerator.FileAlreadyExistsListener,
SourceCodeGenerator.ContinuableExceptionListener
{
private WorkbenchContext context;
private SourceCodeGenerator generator;
private boolean processCanceled = false;
private boolean processErrorless = true;
public ModelSourceGenerationCoordinator(WorkbenchContext context)
{
super();
initialize(context);
}
private void initialize(WorkbenchContext ctx)
{
this.context = ctx;
setGenerator(new SourceCodeGenerator(ctx.getApplicationContext()));
}
private void setGenerator(SourceCodeGenerator generator)
{
this.generator = generator;
this.generator.addContinuableExceptionListener(this);
this.generator.addFileAlreadyExistsListener(this);
}
public void exportModelJavaSource(MWProject project, Collection descriptors)
{
try
{
validateModelSourceRootDirectory(project);
this.generator.generateSourceCode(project, descriptors);
}
catch (CancelException ce)
{
return;
}
showUserFeedback(project);
}
private void validateModelSourceRootDirectory(MWProject project)
{
if (project.getModelSourceDirectoryName().equals(""))
promptForModelSourceRootDirectory(project);
if (project.absoluteModelSourceDirectory().isFile()) // i.e. not a directory
promptForNonFileModelSourceRootDirectory(project);
if (! project.absoluteModelSourceDirectory().exists())
promptToCreateModelSourceRootDirectory(project);
return;
}
/**
* used when there is no directory already chosen
*/
private void promptForModelSourceRootDirectory(MWProject project)
{
String description = resourceRepository().getString("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG_NO_DIRECTORY_CHOSEN.message");
promptForDirectory(project, description);
}
/**
* used when the chosen directory is not actually a directory
*/
private void promptForNonFileModelSourceRootDirectory(MWProject project)
{
String description = resourceRepository().getString("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG_CHOSEN_DIRECTORY_IS_A_FILE.message",
new Object[] {project.absoluteModelSourceDirectory()});
promptForDirectory(project, description);
}
/**
* used when the chosen directory is invalid (e.g. "Z:\foo" if there is no Z drive)
*/
private void promptForValidModelSourceRootDirectory(MWProject project)
{
String description = resourceRepository().getString("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG_CHOSEN_DIRECTORY_IS_INVALID.message",
new Object[] {project.absoluteModelSourceDirectory()});
promptForDirectory(project, description);
}
/**
* used when the chosen directory could not be created (various reasons)
*/
private void promptForCreatableModelSourceRootDirectory(MWProject project)
{
String description = resourceRepository().getString("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG_CHOSEN_DIRECTORY_COULD_NOT_BE_CREATED.message",
new Object[] {project.absoluteModelSourceDirectory()});
promptForDirectory(project, description);
}
private Preferences preferences() {
return this.context.getApplicationContext().getPreferences();
}
//TODO description is not being used, look for the use in 9.0.4
private void promptForDirectory(MWProject project, String description)
{
File startDir = MappingsPlugin.buildExportDirectory(project, project.getModelSourceDirectoryName(), this.preferences());
JFileChooser fileChooser = new FileChooser(startDir, project.getSaveDirectory());
fileChooser.setDialogTitle(resourceRepository().getString("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG.title", project.getName()));
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setApproveButtonText(resourceRepository().getString("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG_SELECT_BUTTON"));
fileChooser.setApproveButtonMnemonic(resourceRepository().getMnemonic("MODEL_SOURCE_ROOT_DIRECTORY_DIALOG_SELECT_BUTTON"));
int option = fileChooser.showSaveDialog(this.context.getCurrentWindow());
if (option == JFileChooser.CANCEL_OPTION) {
throw new CancelException();
}
File directory = fileChooser.getSelectedFile();
project.setModelSourceDirectoryName(directory.getPath());
if ((directory != null) && directory.isAbsolute() && ! directory.equals(project.getSaveDirectory())) {
this.preferences().put(MappingsPlugin.EXPORT_LOCATION_PREFERENCE, directory.getPath());
}
}
private void promptToCreateModelSourceRootDirectory(MWProject project)
{
File canonicalDirectory;
try
{
canonicalDirectory = project.absoluteModelSourceDirectory().getCanonicalFile();
}
catch (IOException ioe)
{
promptForValidModelSourceRootDirectory(project);
return;
}
int input = JOptionPane.showConfirmDialog(this.context.getCurrentWindow(),
resourceRepository().getString("CREATE_MODEL_SOURCE_ROOT_DIRECTORY_DIALOG.message",
new Object[] {canonicalDirectory}),
resourceRepository().getString("CREATE_MODEL_SOURCE_ROOT_DIRECTORY_DIALOG.title"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (input != JOptionPane.YES_OPTION) {
throw new CancelException();
}
if (! project.absoluteModelSourceDirectory().mkdirs()) {
promptForCreatableModelSourceRootDirectory(project);
}
}
private boolean promptToConformEntityBeans()
{
int input = JOptionPane.showConfirmDialog(this.context.getCurrentWindow(),
resourceRepository().getString("sourceCodeGeneration_specCompliance.message"),
resourceRepository().getString("sourceCodeGeneration_specCompliance.title"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
return input == JOptionPane.YES_OPTION;
}
private boolean promptToGenerateAssociatedClasses()
{
int input = JOptionPane.showConfirmDialog(this.context.getCurrentWindow(),
resourceRepository().getString("sourceCodeGeneration_generateAssociatedClasses.message"),
resourceRepository().getString("sourceCodeGeneration_generateAssociatedClasses.title"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
return input == JOptionPane.YES_OPTION;
}
public boolean continueOnException(SourceCodeGenerator.ContinuableExceptionEvent cee)
{
this.processErrorless = false;
ExceptionDialog dialog =
new ExceptionDialog(
resourceRepository().getString("EXPORT_MODEL_SOURCE_CONTINUABLE_ERROR_DIALOG.message"),
cee.getException(),
this.context,
resourceRepository().getString("EXPORT_MODEL_SOURCE_CONTINUABLE_ERROR_DIALOG.title"))
{
protected String buildOKText() {
return resourceRepository().getString("EXPORT_MODEL_SOURCE_YES_BUTTON");
}
protected String buildCancelText() {
return resourceRepository().getString("EXPORT_MODEL_SOURCE_NO_BUTTON");
}
};
dialog.show();
return dialog.wasConfirmed();
}
public boolean fileAlreadyExists(MWProject project,
SourceCodeGenerator.FileAlreadyExistsEvent faee) {
int input = JOptionPane.showConfirmDialog(
this.context.getCurrentWindow(),
resourceRepository().getString("sourceCodeGeneration_fileExists.message"),
resourceRepository().getString("sourceCodeGeneration_fileExists.title"),
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
this.generator.setOverwriteFiles(input == JOptionPane.YES_OPTION);
// Request the user to select another location
if (input == JOptionPane.NO_OPTION) {
promptForModelSourceRootDirectory(project);
validateModelSourceRootDirectory(project);
this.generator.checkForExistingFiles();
}
return (input != JOptionPane.CANCEL_OPTION);
}
private void showUserFeedback(MWProject project)
{
if (this.processCanceled)
return; // user knows (s)he cancelled
if (this.generator.isAnyFileWritten()) {
if (this.processErrorless)
showSuccessDialog(project);
else
showCompletionDialog(project);
}
}
private void showSuccessDialog(MWProject project)
{
JOptionPane.showMessageDialog(this.context.getCurrentWindow(),
resourceRepository().getString("EXPORT_MODEL_SOURCE_SUCCESS_DIALOG.message"),
resourceRepository().getString("EXPORT_MODEL_SOURCE_SUCCESS_DIALOG.title", project.getName()),
JOptionPane.INFORMATION_MESSAGE );
}
private void showCompletionDialog(MWProject project)
{
JOptionPane.showMessageDialog(this.context.getCurrentWindow(),
resourceRepository().getString("EXPORT_MODEL_SOURCE_COMPLETION_DIALOG.message"),
resourceRepository().getString("EXPORT_MODEL_SOURCE_COMPLETION_DIALOG.title", project.getName()),
JOptionPane.INFORMATION_MESSAGE );
}
private ResourceRepository resourceRepository() {
return this.context.getApplicationContext().getResourceRepository();
}
}