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: 3.2M1
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
 *
 *    http://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 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.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import javax.swing.WindowConstants;
import javax.swing.filechooser.FileFilter;

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.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.project.Project;
import org.apache.cayenne.project.validation.ProjectValidator;
import org.apache.cayenne.validation.ValidationFailure;
import org.apache.cayenne.validation.ValidationResult;

/**
 * Controller of the main application frame.
 */
public class CayenneModelerController extends CayenneController {

    protected ProjectController projectController;

    protected CayenneModelerFrame frame;
    
    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);
    }

    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() {

            public void windowClosing(WindowEvent e) {
                getApplication().getActionManager().getAction(ExitAction.class).exit();
            }
        });

        new DropTarget(frame, new DropTargetAdapter() {

            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, 650, 550, 0);
    }

    private boolean processDropAction(Transferable transferable) {
        List fileList;
        try {
            fileList = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor);
        }
        catch (Exception e) {
            return false;
        }

        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() {
        String title = (projectController.getProject().getConfigurationResource() == null)
                ? "[New]"
                : projectController
                        .getProject()
                        .getConfigurationResource()
                        .getURL()
                        .getPath();

        frame.setTitle("* - " + ModelerConstants.TITLE + " - " + title);
    }

    public void projectSavedAction() {
        projectController.setDirty(false);
        projectController.updateProjectControllerPreferences();
        updateStatus("Project saved...");
        frame.setTitle(ModelerConstants.TITLE
                + " - "
                + projectController
                        .getProject()
                        .getConfigurationResource()
                        .getURL()
                        .getPath());
    }

    /**
     * Action method invoked on project closing.
     */
    public void projectClosedAction() {
        // --- update view
        frame.setView(null);

        // repaint is needed, since sometimes there is a
        // trace from menu left on the screen
        frame.repaint();
        frame.setTitle(ModelerConstants.TITLE);

        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);

        frame.setView(new EditorView(projectController));

        projectController.projectOpened();
        application.getActionManager().projectOpened();

        // do status update AFTER the project is actually opened...
        if (project.getConfigurationResource() == null) {
            updateStatus("New project created...");
            frame.setTitle(ModelerConstants.TITLE + "- [New]");
        }
        else {
            updateStatus("Project opened...");
            frame.setTitle(ModelerConstants.TITLE
                    + " - "
                    + project.getConfigurationResource().getURL().getPath());
        }

        // update preferences
        if (project.getConfigurationResource() != null) {
            getLastDirectory().setDirectory(
                    new File(project.getConfigurationResource().getURL().getPath()));
            frame.fireRecentFileListChanged();
        }

        // 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());
        }
    }

    /** Adds path to the list of last opened projects in preferences. */
    public void addToLastProjListAction(String path) {

        Preferences frefLastProjFiles = ModelerPreferences.getLastProjFilesPref();
        List arr = ModelerPreferences.getLastProjFiles();
        // Add proj path to the preferences
        // Prevent duplicate entries.
        if (arr.contains(path)) {
            arr.remove(path);
        }

        arr.add(0, path);
        while (arr.size() > ModelerPreferences.LAST_PROJ_FILES_SIZE) {
            arr.remove(arr.size() - 1);
        }

        try {
            frefLastProjFiles.clear();
        }
        catch (BackingStoreException e) {
            // ignore exception
        }
        int size = arr.size();

        for (int i = 0; i < size; i++) {
            frefLastProjFiles.put(String.valueOf(i), arr.get(i).toString());
        }
    }

    /**
     * Performs status bar update with a message. Message will dissappear 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) {
            Thread cleanup = new ExpireThread(message, 6);
            cleanup.start();
        }
    }

    class ExpireThread extends Thread {

        protected int seconds;
        protected String message;

        public ExpireThread(String message, int seconds) {
            this.seconds = seconds;
            this.message = message;
        }

        public void run() {
            try {
                sleep(seconds * 1000);
            }
            catch (InterruptedException e) {
                // ignore exception
            }

            if (message.equals(frame.getStatus().getText())) {
                updateStatus(null);
            }
        }
    }

    public void changePathInLastProjListAction(String oldPath, String newPath) {
        Preferences frefLastProjFiles = ModelerPreferences.getLastProjFilesPref();
        List arr = ModelerPreferences.getLastProjFiles();
        // Add proj path to the preferences
        // Prevent duplicate entries.
        if (arr.contains(oldPath)) {
            arr.remove(oldPath);
        }

        if (arr.contains(newPath)) {
            arr.remove(newPath);
        }

        arr.add(0, newPath);
        while (arr.size() > ModelerPreferences.LAST_PROJ_FILES_SIZE) {
            arr.remove(arr.size() - 1);
        }

        try {
            frefLastProjFiles.clear();
        }
        catch (BackingStoreException e) {
            // ignore exception
        }
        int size = arr.size();

        for (int i = 0; i < size; i++) {
            frefLastProjFiles.put(String.valueOf(i), arr.get(i).toString());
        }

        getLastDirectory().setDirectory(new File(newPath));
        frame.fireRecentFileListChanged();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy