All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cayenne.modeler.CayenneModelerController Maven / Gradle / Ivy

There is a newer version: 5.0-M1
Show newest version
/*****************************************************************
 *   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