/******************************************************************************* * 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; import java.io.File; import java.util.prefs.Preferences; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; 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.uitools.FileChooser; import org.eclipse.persistence.tools.workbench.mappingsmodel.project.MWProject; import org.eclipse.persistence.tools.workbench.uitools.CancelException; import org.eclipse.persistence.tools.workbench.uitools.LabelArea; import org.eclipse.persistence.tools.workbench.utility.io.FileTools; import org.eclipse.persistence.tools.workbench.utility.string.StringTools; /** * This class is responsible for * - gathering user information * - displaying information back to the user * during the process of generating deployment XML for a project. */ public final class ProjectDeploymentXmlGenerationCoordinator { private WorkbenchContext context; public ProjectDeploymentXmlGenerationCoordinator(WorkbenchContext context) { super(); this.context = context; } public boolean exportProjectDeploymentXml(MWProject project) { try { configureProjectDeploymentXMLFile(project); checkProjectProblems(project); } catch (CancelException ex) { return false; } if (project.deploymentXMLFile().isDirectory()) { this.showInvalidFileDialog(project); return false; } try { project.exportDeploymentXML(); } catch (NoClassDefFoundError error) { if (error.getMessage().startsWith("oracle.xdb")) { this.showMissingXdbJarDialog(); return false; } else { throw error; } } showSuccessDialog(project); return true; } private void configureProjectDeploymentXMLFile(MWProject project) { // if the project already has a file specified, just use that... if ( ! StringTools.stringIsEmpty(project.getDeploymentXMLFileName())) { return; } // ...otherwise prompt the user for a file File directory = MappingsPlugin.buildExportDirectory(project, "", this.preferences()); File initialFile = new File(directory, project.getName() + ".xml"); // prompt the user LocalFileChooser chooser = new LocalFileChooser(this.context, directory, project.getSaveDirectory()); chooser.setDialogTitle(this.resourceRepository().getString("PROJECT_XML_SAVE_AS_DIALOG_TITLE")); chooser.setAcceptAllFileFilterUsed(true); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setMultiSelectionEnabled(false); chooser.setSelectedFile(initialFile); chooser.setFileFilter(this.buildXMLFileFilter()); int result = chooser.showSaveDialog(this.context.getCurrentWindow()); if (result == JFileChooser.CANCEL_OPTION) { throw new CancelException(); } // update the project with the new file File selectedFile = chooser.getSelectedFile(); project.setDeploymentXMLFileName(selectedFile.getPath()); // update the preferences if appropriate File selectedDir = selectedFile.getParentFile(); if ((selectedDir != null) && selectedDir.isAbsolute() && ! selectedDir.equals(project.getSaveDirectory())) { this.preferences().put(MappingsPlugin.EXPORT_LOCATION_PREFERENCE, selectedDir.getPath()); } } private Preferences preferences() { return this.context.getApplicationContext().getPreferences(); } private FileFilter buildXMLFileFilter() { return new FileFilter() { public boolean accept(File file) { return file.isDirectory() || ".xml".equals(FileTools.extension(file).toLowerCase()); } public String getDescription() { return resourceRepository().getString("PROJECT_XML_SAVE_AS_DIALOG_XML_DESCRIPTION"); } }; } private void checkProjectProblems(MWProject project) { if ( ! project.hasBranchProblems()) { return; } int response = JOptionPane.showConfirmDialog(this.context.getCurrentWindow(), new LabelArea(resourceRepository().getString("PROJECT_XML_PROJECT_PROBLEMS_DIALOG.message", StringTools.CR)), resourceRepository().getString("PROJECT_XML_PROJECT_PROBLEMS_DIALOG.title", project.getName()), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE ); if (response != JOptionPane.YES_OPTION) { throw new CancelException(); } } private void showInvalidFileDialog(MWProject project) { JOptionPane.showMessageDialog( this.context.getCurrentWindow(), resourceRepository().getString("GENERATE_PROJECT_XML_INVALID_FILE_DIALOG.message", project.deploymentXMLFile()), resourceRepository().getString("GENERATE_PROJECT_XML_INVALID_FILE_DIALOG.title", project.getName()), JOptionPane.ERROR_MESSAGE ); } private void showMissingXdbJarDialog() { JOptionPane.showMessageDialog( this.context.getCurrentWindow(), resourceRepository().getString("GENERATE_PROJECT_XML_MISSING_XDB_JAR.message", StringTools.CR), resourceRepository().getString("GENERATE_PROJECT_XML_MISSING_XDB_JAR.title"), JOptionPane.ERROR_MESSAGE ); } private void showSuccessDialog(MWProject project) { JOptionPane.showMessageDialog( this.context.getCurrentWindow(), resourceRepository().getString("GENERATE_PROJECT_XML_SUCCESS_DIALOG.message"), resourceRepository().getString("GENERATE_PROJECT_XML_SUCCESS_DIALOG.title", project.getName()), JOptionPane.INFORMATION_MESSAGE ); } ResourceRepository resourceRepository() { return this.context.getApplicationContext().getResourceRepository(); } /** * This extension over the <code>JFileChooser</code> makes sure the selected * file is valid, ie is not Read-Only. If it's a different file, then prompt * the user to make sure it is ok to overwrite it. */ private class LocalFileChooser extends FileChooser { private final WorkbenchContext workbenchContext; private static final long serialVersionUID = 1L; private LocalFileChooser(WorkbenchContext workbenchContext, File currentDirectory, File rootFile) { super(currentDirectory, rootFile); this.workbenchContext = workbenchContext; } /** * Determines whether the selected file can be used as the new location to * persist the document. */ public void approveSelection() { int result = canReplaceExistingFile(); if (result == JOptionPane.YES_OPTION) super.approveSelection(); else if (result == JOptionPane.CANCEL_OPTION) cancelSelection(); } /** * Verifies if the file (which is currently selected) can be replaced with * the document to be saved. * * @return <code>JOptionPane.YES_OPTION</code> if the file is not * Read-Only or can be replaced, <code>JOptionPane.NO_OPTION</code> if the * document can't be saved because the selected file is Read-Only or the * user said no to replace it, or <code>JOptionPane.NO_OPTION</code> if * the user does not want to replace the file and canceled the confirm * dialog */ private int canReplaceExistingFile() { File file = getSelectedFile(); // The file exist but is marked as Read-Only, show we can't save it if (file.exists() && !file.canWrite()) { String message = resourceRepository().getString("PROJECT_XML_SAVE_AS_DIALOG_CANT_SAVE", file); LabelArea label = new LabelArea(message); JOptionPane.showMessageDialog ( this.workbenchContext.getCurrentWindow(), label, resourceRepository().getString("PROJECT_XML_SAVE_AS_DIALOG_CANT_SAVE_TITLE"), JOptionPane.WARNING_MESSAGE ); return JOptionPane.NO_OPTION; } // The file exist if (file.exists()) { String message = resourceRepository().getString("PROJECT_XML_SAVE_AS_DIALOG_REPLACE", getSelectedFile().getPath()); LabelArea label = new LabelArea(message); return JOptionPane.showConfirmDialog ( this.workbenchContext.getCurrentWindow(), label, resourceRepository().getString("PROJECT_XML_SAVE_AS_DIALOG_REPLACE_TITLE"), JOptionPane.YES_NO_CANCEL_OPTION ); } return JOptionPane.YES_OPTION; } } }