Package org.intellij.vcs.mks

Source Code of org.intellij.vcs.mks.MksVcs$TasksModel

package org.intellij.vcs.mks;

import com.intellij.ProjectTopics;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeProvider;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.diff.DiffProvider;
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.AbstractTableCellEditor;
import org.intellij.vcs.mks.actions.api.CheckoutAPICommand;
import org.intellij.vcs.mks.history.MksVcsHistoryProvider;
import org.intellij.vcs.mks.realtime.*;
import org.intellij.vcs.mks.sicommands.api.ListServersAPI;
import org.intellij.vcs.mks.sicommands.cli.*;
import org.intellij.vcs.mks.update.MksUpdateEnvironment;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class MksVcs extends AbstractVcs implements MksCLIConfiguration {
    static final Logger LOGGER = Logger.getInstance(MksVcs.class.getName());
    static final boolean DEBUG = false;

    private JTextPane mksTextArea;
    private final SandboxCache sandboxCache;
    private MessageBusConnection myMessageBusConnection;
    private MksVcs.TasksModel tasksModel;

    private final MksCheckinEnvironment mksCheckinEnvironment = new MksCheckinEnvironment(this);
    //private final MksRollbackEnvironment rollbackEnvironment= new MksRollbackEnvironment(this);
    private final MksChangeListAdapter changeListAdapter = new MksChangeListAdapter(this);
    private final EditFileProvider editFileProvider = new _EditFileProvider(this);
    private final MksDiffProvider diffProvider = new MksDiffProvider(this);
    private final VcsHistoryProvider vcsHistoryProvider = new MksVcsHistoryProvider(this);
    private final MksUpdateEnvironment updateEnvironment = new MksUpdateEnvironment(this);
    @NonNls
    public static final String VCS_NAME = "MKS";
    public static final VcsKey OUR_KEY = createKey(VCS_NAME);
    private static final String MKS_TOOLWINDOW = "MKS";
    @NonNls
    public static final String PROJECT_PJ_FILE = "project.pj";
    @NonNls
    private static final String ICONS_MKS_GIF = "/icons/mks.gif";
    private Boolean isMks2007 = null;
    private MksRollbackEnvironment rollbackEnvironment = new MksRollbackEnvironment(this);

    public MksVcs(final Project project) {
        super(project, VCS_NAME);
        sandboxCache = project.getComponent(SandboxCache.class);


//        sandboxCache = new NativeSandboxCacheImpl(project);
    }

  public static void invokeOnEventDispatchThreadAndWait(Runnable runnable) throws VcsException {
    if (!SwingUtilities.isEventDispatchThread()) {
      try {
        SwingUtilities.invokeAndWait(runnable);
      } catch (InterruptedException e1) {
        Thread.currentThread().interrupt();
      } catch (InvocationTargetException e1) {
        throw new VcsException(e1.getTargetException());
      }
    } else {
      runnable.run();
    }
  }
  public static void invokeLaterOnEventDispatchThread(Runnable runnable) {
    if (!SwingUtilities.isEventDispatchThread()) {
      SwingUtilities.invokeLater(runnable);
    } else {
      runnable.run();
    }
  }

    public static String getRelativePath(@NotNull FilePath filePath, @NotNull FilePath parentPath) {
        return VfsUtil.getRelativePath(filePath.getVirtualFile(), parentPath.getVirtualFile(), '/');
    }

    public static String getRelativePath(@NotNull VirtualFile virtualFile, @NotNull VirtualFile parentVirtualFile) {
    return VfsUtil.getRelativePath(virtualFile, parentVirtualFile, '/');
  }


    @Override
    public Configurable getConfigurable() {
        return new MksConfigurableForm(ApplicationManager.getApplication().getComponent(MksConfiguration.class));
    }

    @Override
    public String getDisplayName() {
        return VCS_NAME;
    }

    public MksChangeListAdapter getChangeListAdapter() {
        return changeListAdapter;
    }

    public void showErrors(final java.util.List<VcsException> list, final String action) {
        if (!list.isEmpty()) {
            final StringBuffer buffer = new StringBuffer(mksTextArea.getText());
            buffer.append("\n");
            buffer.append(action).append(" Error: ");
            VcsException e;
            for (Iterator<VcsException> iterator = list.iterator(); iterator.hasNext(); buffer.append(e.getMessage())) {
                //noinspection ThrowableResultOfMethodCallIgnored
                e = iterator.next();
                buffer.append("\n");
            }
            mksTextArea.setText(buffer.toString());
        }
    }

    private void initToolWindow() {
        final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
        final JToolBar toolbar = new JToolBar();
        final Action viewSandboxesAction = new AbstractAction("view sandboxes") {
            public void actionPerformed(final ActionEvent event) {
                final StringWriter stringWriter = new StringWriter();
                final PrintWriter pw = new PrintWriter(stringWriter);
                pw.println(mksTextArea.getText());
                sandboxCache.dumpStateOn(pw);
                mksTextArea.setText(stringWriter.toString());
            }
        };
        toolbar.add(viewSandboxesAction);
        final JPanel mksPanel = new JPanel(new BorderLayout());
        mksPanel.add(toolbar, BorderLayout.NORTH);
        final JTabbedPane tabbedPane = new JTabbedPane();

        this.mksTextArea = createMksLogTextPane();
        final JPanel panelDebug = new JPanel(new BorderLayout());
        panelDebug.add(new JScrollPane(mksTextArea), BorderLayout.CENTER);
        tabbedPane.add(panelDebug, "Log", 0);


        tabbedPane.add(createCommandStatisticsPanel(), "Command statistics");
        tabbedPane.add(createTasksPanel(), "Daemon processes");
        mksPanel.add(tabbedPane, BorderLayout.CENTER);
        invokeLaterOnEventDispatchThread(new Runnable() {
            @Override
            public void run() {
                registerToolWindow(toolWindowManager, mksPanel);
            }
        });

        final JPopupMenu menu = new JPopupMenu();
        final JMenuItem item = new JMenuItem("Clear");
        item.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                mksTextArea.setText("");
            }
        });
        menu.add(item);
        mksTextArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(final MouseEvent e) {
                maybeShowPopup(e, menu);
            }

            @Override
            public void mouseReleased(final MouseEvent e) {
                maybeShowPopup(e, menu);
            }
        });
    }

    class TasksModel extends AbstractTableModel {
        private final String[] COLUMNS = {"Name", "Running", "Restart"};
        final int NAME = 0;
        final int STATE = 1;
        final int RESTART = 2;


        public int getColumnCount() {
            return COLUMNS.length;
        }

        public int getRowCount() {
            return myProject.getComponent(LongRunningTaskRepository.class).size();
        }

        public Object getValueAt(final int row, final int column) {
            final LongRunningTask task = myProject.getComponent(LongRunningTaskRepository.class).get(row);
            if (task == null) {
                return null;
            }
            switch (column) {
                case NAME:
                    return task.getDescription();
                case STATE:
                    return task.isAlive();
                case RESTART:
                    return false;
                default:
                    return null;
            }
        }

        @Override
        public boolean isCellEditable(final int row, final int column) {
            return RESTART == column;
        }

        @Override
        public Class<?> getColumnClass(final int column) {
            switch (column) {
                case NAME:
                    return String.class;
                case STATE:
                    return Boolean.class;
                case RESTART:
                    return Boolean.class;
                default:
                    return Object.class;
            }
        }

        @Override
        public String getColumnName(final int column) {
            return COLUMNS[column];
        }

        public void refresh() {
            fireTableDataChanged();
        }

    }

    private Component createTasksPanel() {
        final JTable tasksTable = new JTable();

        final JPanel jPanel = new JPanel();
        jPanel.setLayout(new BorderLayout());
        final JPanel buttonsPanel = new JPanel();
        buttonsPanel.add(new JButton(new AbstractAction("Refresh") {
            public void actionPerformed(final ActionEvent event) {
                tasksModel.refresh();
            }
        }));
        tasksModel = new TasksModel();
        jPanel.add(buttonsPanel, BorderLayout.NORTH);
        jPanel.add(new JScrollPane(tasksTable), BorderLayout.CENTER);
        tasksTable.setModel(tasksModel);
        tasksTable.getColumnModel().
                getColumn(tasksModel.RESTART).setCellRenderer(new TableCellRenderer() {
            public Component getTableCellRendererComponent(final JTable jTable, final Object o, final boolean b,
                                                           final boolean b1, final int i, final int i1) {
                return new JButton(new AbstractAction("restart") {
                    public void actionPerformed(final ActionEvent e) {
                        final SandboxListSynchronizer synchronizer =
                                ApplicationManager.getApplication().getComponent(SandboxListSynchronizer.class);
                        synchronizer.restart();
                    }
                });
            }
        });
        tasksTable.getColumnModel().getColumn(tasksModel.RESTART).setCellEditor(new AbstractTableCellEditor() {
            public Object getCellEditorValue() {
                return true;
            }

            public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, final int row,
                                                         final int column) {
                final JButton button = new JButton("restart");
                button.addActionListener(new ActionListener() {
                    public void actionPerformed(final ActionEvent event) {
                        final LongRunningTask task = myProject.getComponent(LongRunningTaskRepository.class).get(row);
                        LOGGER.debug("restarting task " + task);
                        task.restart();
                    }
                });
                return button;
            }
        });
        return jPanel;

    }

    private final CommandExecutionAdapter commandExecutionAdapter = new CommandExecutionAdapter();

    public CommandExecutionListener getCommandExecutionListener() {
        return commandExecutionAdapter;
    }

    public boolean isMks2007() {
        if (null == this.isMks2007) {
            final SiAboutCommand command =
                    new SiAboutCommand(new ArrayList<VcsException>(), this);
            command.execute();
            if (!command.foundError()) {
                this.isMks2007 = command.isMks2007();
            }
        }
        return this.isMks2007;
    }

    private Component createCommandStatisticsPanel() {
        final JTable commandsTable = new JTable();

        final JPanel jPanel = new JPanel();
        final JPanel buttonsPanel = new JPanel();
        buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
        buttonsPanel.add(new JButton(new AbstractAction("Clear statistics") {
            public void actionPerformed(final ActionEvent event) {
                commandExecutionAdapter.clear();
            }
        }));
        jPanel.setLayout(new BorderLayout());
        jPanel.add(buttonsPanel, BorderLayout.NORTH);
        jPanel.add(new JScrollPane(commandsTable), BorderLayout.CENTER);
        commandsTable.setModel(commandExecutionAdapter);
        return jPanel;

    }

    private JTextPane createMksLogTextPane() {
        final JTextPane mksTextArea = new JTextPane();
        mksTextArea.setEditable(false);
        final javax.swing.text.Style def = StyleContext.getDefaultStyleContext().getStyle("default");
        final javax.swing.text.Style regular = mksTextArea.addStyle("REGULAR", def);
        StyleConstants.setFontFamily(def, "SansSerif");
        javax.swing.text.Style s = mksTextArea.addStyle(StyleConstants.Italic.toString(), regular);
        StyleConstants.setItalic(s, true);
        s = mksTextArea.addStyle(StyleConstants.Bold.toString(), regular);
        StyleConstants.setBold(s, true);
        return mksTextArea;
    }

    private ToolWindow registerToolWindow(final ToolWindowManager toolWindowManager, final JPanel mksPanel) {
        final ToolWindow toolWindow = toolWindowManager.registerToolWindow(MKS_TOOLWINDOW, true, ToolWindowAnchor.BOTTOM);
        final ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
        final Content content = contentFactory.createContent(mksPanel, "", false); // first arg is a JPanel
        content.setCloseable(false);
        toolWindow.getContentManager().addContent(content);

        toolWindow.setIcon(IconLoader.getIcon(ICONS_MKS_GIF, getClass()));
        return toolWindow;
    }

    private void maybeShowPopup(final MouseEvent e, final JPopupMenu menu) {
        if (e.isPopupTrigger()) {
            menu.show(mksTextArea, e.getX(), e.getY());
        }
    }

    private void unregisterToolWindow() {
        ToolWindowManager.getInstance(myProject).unregisterToolWindow("MKS");
    }

    public static MksVcs getInstance(final Project project) {
        return (MksVcs) ProjectLevelVcsManager.getInstance(project).findVcsByName(VCS_NAME);
    }


    public void debug(final String s) {
        ProjectLevelVcsManager.getInstance(myProject).addMessageToConsoleWindow(s, null);
        debug(s, null);
    }

    /**
     * checks if the file is in a directory controlled by mks and is not a mks project file
     *
     * @param filePath the file designation
     * @return true if the file is in a directory controlled by mks
     */
    @Override
    public synchronized boolean fileIsUnderVcs(final FilePath filePath) {
//    System.out.println("super.fileIsUnderVcs " + filePath + " = " + super.fileIsUnderVcs(filePath));
        return super.fileIsUnderVcs(filePath)
                && !getSandboxCache().isSandboxProject(filePath.getVirtualFile());
    }

    private void debug(final String s, final Exception e) {
        final StringWriter sw = new StringWriter();
        final PrintWriter pw = new PrintWriter(sw);
        pw.println(s);
        if (e != null) {
            LOGGER.debug(s, e);
            e.printStackTrace(pw);
        } else {
            LOGGER.debug(s);
        }
        if (mksTextArea != null) {
            pw.flush();
            try {
                mksTextArea.getDocument().insertString(mksTextArea.getDocument().getLength(), sw.toString(), null);
            } catch (BadLocationException e1) {
                LOGGER.warn(e1);
            }
        }
    }

    @Override
    public DiffProvider getDiffProvider() {
        return diffProvider;
    }

    public Project getProject() {
        return myProject;
    }

    @Override
    @NotNull
    public ChangeProvider getChangeProvider() {
        return myProject.getComponent(MKSChangeProvider.class);
    }

    @Override
    @NotNull
    public String getMksSiEncoding(final String command) {
        return ApplicationManager.getApplication().getComponent(MksConfiguration.class).getMksSiEncoding(command);
    }

    @Override
    @NotNull
    public String getDatePattern() {
        return ApplicationManager.getApplication().getComponent(MksConfiguration.class).getDatePattern();
    }

    private class _EditFileProvider implements EditFileProvider {
        private final MksVcs mksVcs;

        public _EditFileProvider(final MksVcs mksVcs) {
            this.mksVcs = mksVcs;
        }

    @Override
    public void editFiles(final VirtualFile[] virtualFiles) throws VcsException {
      final DispatchBySandboxCommand dispatchCommand = new DispatchBySandboxCommand(mksVcs, virtualFiles);
      dispatchCommand.execute();
      if (!dispatchCommand.getNotInSandboxFiles().isEmpty()) {
        Runnable runnable = new Runnable() {
          public void run() {
            Messages.showErrorDialog(MksBundle.message("unable.to.find.the.sandboxes.for.the.files.title"),
                MksBundle.message("could.not.start.checkout"));
          }
        };
        MksVcs.invokeLaterOnEventDispatchThread(runnable);

        return;
      }
      for (final Map.Entry<MksSandboxInfo, ArrayList<VirtualFile>> entry : dispatchCommand.filesBySandbox.entrySet()) {
        final MksSandboxInfo sandbox = entry.getKey();
        final ArrayList<VirtualFile> files = entry.getValue();
        final List<VcsException> errors = new ArrayList<VcsException>();

                final CheckoutAPICommand command = new CheckoutAPICommand();
                command.executeCommand(MksVcs.this, errors, files.toArray(new VirtualFile[files.size()]));
                    if (!errors.isEmpty()) {
                        //noinspection ThrowableResultOfMethodCallIgnored
                        Runnable runnable = new Runnable() {
                            public void run() {
                                Messages.showErrorDialog(errors.get(0).getLocalizedMessage(),
                                        MksBundle.message("could.not.start.checkout"));
                            }
                        };
                        MksVcs.invokeLaterOnEventDispatchThread(runnable);

                        return;
                    }
            }
    }

        @Override
        public String getRequestText() {
            return MksBundle.message("edit.file.provider.request.text");
        }
    }

    @Override
    @Nullable
    public EditFileProvider getEditFileProvider() {
        return editFileProvider;
    }

    public Map<MksSandboxInfo, ArrayList<VirtualFile>> dispatchBySandbox(final VirtualFile[] files, final boolean topSandboxOnly) {
        final DispatchBySandboxCommand dispatchCommand =
                new DispatchBySandboxCommand(this, files, topSandboxOnly);
        dispatchCommand.execute();
        return dispatchCommand.filesBySandbox;
    }

    public Map<MksSandboxInfo, ArrayList<VirtualFile>> dispatchBySandbox(final VirtualFile[] files) {
        return dispatchBySandbox(files, true);
    }

    /**
     * @return the list of available si commands, used for encoding settings
     */
    public static String[] getCommands() {
        return new String[]{
                AbstractViewSandboxCommand.COMMAND,
                GetContentRevision.COMMAND,
                GetRevisionInfo.COMMAND,
                ListChangePackages.COMMAND,
                ListSandboxes.COMMAND,
                ListServersAPI.COMMAND,
                LockMemberCommand.COMMAND,
                RenameChangePackage.COMMAND,
                SiConnectCommand.COMMAND,
                UnlockMemberCommand.COMMAND,
                ViewNonMembersCommand.COMMAND
        };
    }

    @Override
    @Nullable
    public CheckinEnvironment getCheckinEnvironment() {
        return mksCheckinEnvironment;
    }

    public SandboxCache getSandboxCache() {
        return sandboxCache;
    }

    @Override
    public void activate() {
        LOGGER.debug("activate [" + myProject + "]");
        try {
            URL resource = getClass().getResource("/" + "org.apache.commons.httpclient.MultiThreadedHttpConnectionManager".replace('.', '/') + ".class");
            if (!resource.toExternalForm().contains("/mksapi-without-commons-log")) {
                LOGGER.warn("not loading commons-http from mks jar : " + resource.toExternalForm());
            }
        } catch (Exception e) {
            LOGGER.error("failed locating commons-httpclient", e);
        }
        super.activate();
        final ChangeListManager changeListManager = ChangeListManager.getInstance(getProject());
        changeListManager.addChangeListListener(changeListAdapter);
        // the 2 cases need to be handled, as postStartup is not run if the vcs with the project after project loading
        // (eg when the user chooses a vcs for the project)
        if (!myProject.isInitialized()) {
            StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() {
                @Override
                public void run() {
                    postProjectLoadInit();
                }
            });
        } else {
            postProjectLoadInit();
        }
        myMessageBusConnection = getProject().getMessageBus().connect();
        myMessageBusConnection.subscribe(ProjectTopics.PROJECT_ROOTS, sandboxCache);
    }

    private void postProjectLoadInit() {
        if (!myProject.isDisposed()) {
/*
            final SandboxListSynchronizer synchronizer =
                    ApplicationManager.getApplication().getComponent(SandboxListSynchronizer.class);
            if (synchronizer == null) {
                LOGGER.error("SandboxSynchronizer applicationComponent is not running, MKS vcs will not be loaded");
                return;
            }
            myProject.getComponent(LongRunningTaskRepository.class).add(synchronizer);
            synchronizer.addListener(getSandboxCache());
*/
            initToolWindow();
        }
    }


    @Override
    public void deactivate() {
        try {
            final ChangeListManager changeListManager = ChangeListManager.getInstance(getProject());
            changeListManager.removeChangeListListener(changeListAdapter);
            sandboxCache.release();

            SandboxListSynchronizer component = ApplicationManager.getApplication().getComponent(SandboxListSynchronizer.class);
            if (component != null) {
                component.removeListener(getSandboxCache());
            }
            if (myMessageBusConnection != null) {
                myMessageBusConnection.disconnect();
            }
            unregisterToolWindow();
        } finally {
            super.deactivate();
        }
    }


    /**
     * used for the "Show History for Class/Method/Field/Selection..."
     * The action is not available if getVcsBlockHistoryProvider() returns
     * null.
     *
     * @return
     */
    @Override
    @Nullable
    public VcsHistoryProvider getVcsBlockHistoryProvider() {
        return getVcsHistoryProvider();
    }

    @Override
    @Nullable
    public VcsHistoryProvider getVcsHistoryProvider() {
        return vcsHistoryProvider;
    }

    @Override
    @Nullable
    public UpdateEnvironment getStatusEnvironment() {
        return updateEnvironment;
    }

    @Override
    public boolean isVersionedDirectory(final VirtualFile virtualFile) {
        // does not work currently as the vcs is not initialized yet ...
        final VirtualFile child = virtualFile.findChild(PROJECT_PJ_FILE);
        return null != child && child.exists();
    }

    @Override
    public boolean areDirectoriesVersionedItems() {
        return false;
    }

    @Override
    public VcsType getType() {
        return VcsType.centralized;
    }

    @Nullable
    @Override
    public RollbackEnvironment getRollbackEnvironment() {
        return rollbackEnvironment;
    }
}
TOP

Related Classes of org.intellij.vcs.mks.MksVcs$TasksModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.