
org.apache.cayenne.modeler.CayenneModelerController Maven / Gradle / Ivy
/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.modeler;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.modeler.action.ExitAction;
import org.apache.cayenne.modeler.action.OpenProjectAction;
import org.apache.cayenne.modeler.dialog.validator.ValidatorDialog;
import org.apache.cayenne.modeler.editor.EditorView;
import org.apache.cayenne.modeler.editor.DbImportController;
import org.apache.cayenne.modeler.init.platform.PlatformInitializer;
import org.apache.cayenne.modeler.pref.ComponentGeometry;
import org.apache.cayenne.modeler.pref.FSPath;
import org.apache.cayenne.modeler.util.CayenneController;
import org.apache.cayenne.modeler.util.FileFilters;
import org.apache.cayenne.modeler.util.state.ProjectStateUtil;
import org.apache.cayenne.project.Project;
import org.apache.cayenne.project.validation.ProjectValidator;
import org.apache.cayenne.validation.ValidationFailure;
import org.apache.cayenne.validation.ValidationResult;
import javax.swing.WindowConstants;
import javax.swing.filechooser.FileFilter;
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
/**
* Controller of the main application frame.
*/
public class CayenneModelerController extends CayenneController {
private static final ProjectStateUtil PROJECT_STATE_UTIL = new ProjectStateUtil();
private ProjectController projectController;
protected CayenneModelerFrame frame;
private EditorView editorView;
private DbImportController dbImportController;
public CayenneModelerController(){
}
public CayenneModelerController(Application application) {
super(application);
this.frame = new CayenneModelerFrame(application.getActionManager());
application.getInjector().getInstance(PlatformInitializer.class).setupMenus(frame);
this.projectController = new ProjectController(this);
this.dbImportController = new DbImportController();
}
@Override
public Component getView() {
return frame;
}
public ProjectController getProjectController() {
return projectController;
}
public FSPath getLastEOModelDirectory() {
// find start directory in preferences
FSPath path = (FSPath) application
.getCayenneProjectPreferences()
.getProjectDetailObject(FSPath.class, getViewPreferences().node("lastEOMDir"));
if (path.getPath() == null) {
path.setPath(getLastDirectory().getPath());
}
return path;
}
protected void initBindings() {
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
PROJECT_STATE_UTIL.saveLastState(projectController);
getApplication().getActionManager().getAction(ExitAction.class).exit();
}
});
// Register a hook to save the window position when quit via the app menu.
// This is in Mac OSX only.
if (System.getProperty("os.name").startsWith("Mac OS")) {
Runnable runner = () -> PROJECT_STATE_UTIL.saveLastState(projectController);
Runtime.getRuntime().addShutdownHook(new Thread(runner, "Window Prefs Hook"));
}
new DropTarget(frame, new DropTargetAdapter() {
@Override
public void drop(DropTargetDropEvent dtde) {
dtde.acceptDrop(dtde.getDropAction());
Transferable transferable = dtde.getTransferable();
dtde.dropComplete(processDropAction(transferable));
}
});
ComponentGeometry geometry = new ComponentGeometry(frame.getClass(), null);
geometry.bind(frame, 1200, 720, 0);
}
@SuppressWarnings("unchecked")
private boolean processDropAction(Transferable transferable) {
List fileList;
try {
fileList = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor);
} catch (Exception e) {
return false;
}
if (fileList != null) {
File transferFile = fileList.get(0);
if (transferFile.isFile()) {
FileFilter filter = FileFilters.getApplicationFilter();
if (filter.accept(transferFile)) {
ActionEvent e = new ActionEvent(transferFile, ActionEvent.ACTION_PERFORMED, "OpenProject");
Application.getInstance().getActionManager().getAction(OpenProjectAction.class).actionPerformed(e);
return true;
}
}
}
return false;
}
public void startupAction() {
initBindings();
frame.setVisible(true);
}
public void projectModifiedAction() {
frame.setTitle("* - " + getProjectLocationString());
}
public void projectSavedAction() {
projectController.setDirty(false);
projectController.updateProjectControllerPreferences();
updateStatus("Project saved...");
frame.setTitle(getProjectLocationString());
}
/**
* Action method invoked on project closing.
*/
public void projectClosedAction() {
PROJECT_STATE_UTIL.saveLastState(projectController);
// --- update view
frame.setView(null);
// repaint is needed, since sometimes there is a
// trace from menu left on the screen
frame.repaint();
frame.setTitle("");
projectController.setProject(null);
projectController.reset();
application.getActionManager().projectClosed();
updateStatus("Project Closed...");
}
/**
* Handles project opening control. Updates main frame, then delegates control to
* child controllers.
*/
public void projectOpenedAction(Project project) {
projectController.setProject(project);
editorView = new EditorView(projectController);
frame.setView(editorView);
projectController.projectOpened();
application.getActionManager().projectOpened();
// do status update AFTER the project is actually opened...
if (project.getConfigurationResource() == null) {
updateStatus("New project created...");
} else {
updateStatus("Project opened...");
try {
// update preferences
File file = new File(project.getConfigurationResource().getURL().toURI());
getLastDirectory().setDirectory(file);
frame.fireRecentFileListChanged();
} catch (URISyntaxException ignore) {
}
}
frame.setTitle(getProjectLocationString());
PROJECT_STATE_UTIL.fireLastState(projectController);
// for validation purposes combine load failures with post-load validation (not
// sure if that'll cause duplicate messages?).
List allFailures = new ArrayList<>();
Collection loadFailures = project.getConfigurationTree().getLoadFailures();
if (!loadFailures.isEmpty()) {
// mark project as unsaved
project.setModified(true);
projectController.setDirty(true);
allFailures.addAll(loadFailures);
}
ProjectValidator projectValidator = getApplication().getInjector().getInstance(ProjectValidator.class);
ValidationResult validationResult = projectValidator.validate(project.getRootNode());
allFailures.addAll(validationResult.getFailures());
if (!allFailures.isEmpty()) {
ValidatorDialog.showDialog(frame, validationResult.getFailures());
}
}
public EditorView getEditorView() {
return editorView;
}
/** Adds path to the list of last opened projects in preferences. */
public void addToLastProjListAction(File file) {
Preferences prefLastProjFiles = ModelerPreferences.getLastProjFilesPref();
List arr = ModelerPreferences.getLastProjFiles();
// Add proj path to the preferences
arr.remove(file);
arr.add(0, file);
while (arr.size() > ModelerPreferences.LAST_PROJ_FILES_SIZE) {
arr.remove(arr.size() - 1);
}
try {
prefLastProjFiles.clear();
} catch (BackingStoreException ignored) {
// ignore exception
}
int size = arr.size();
for (int i = 0; i < size; i++) {
prefLastProjFiles.put(String.valueOf(i), arr.get(i).getAbsolutePath());
}
}
public void changePathInLastProjListAction(File oldFile, File newFile) {
ModelerPreferences.getLastProjFiles().remove(oldFile);
addToLastProjListAction(newFile);
getLastDirectory().setDirectory(newFile);
frame.fireRecentFileListChanged();
}
/**
* Performs status bar update with a message. Message will disappear in 6 seconds.
*/
public void updateStatus(String message) {
frame.getStatus().setText(message);
// start message cleanup thread that would remove the message after X seconds
if (message != null && message.trim().length() > 0) {
new Thread(() -> {
try {
Thread.sleep(6 * 10000);
} catch (InterruptedException ignore){
}
if (message.equals(frame.getStatus().getText())) {
updateStatus(null);
}
}).start();
}
}
public DbImportController getDbImportController() {
return dbImportController;
}
protected String getProjectLocationString() {
if(projectController.getProject().getConfigurationResource() == null) {
return "[New Project]";
}
try {
File projectFile = new File(projectController.getProject().getConfigurationResource().getURL().toURI());
return projectFile.toString();
} catch (URISyntaxException e) {
throw new CayenneRuntimeException("Invalid project source URL", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy