org.eclipse.jst.common.jdt.internal.integration.ui.WTPUIWorkingCopyManager.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.common.jdt.internal.integration.ui.WTPUIWorkingCopyManager.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.common.jdt.internal.integration.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider;
import org.eclipse.jdt.internal.ui.javaeditor.InternalClassFileEditorInput;
import org.eclipse.jdt.ui.IWorkingCopyManager;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jst.common.jdt.internal.integration.WTPWorkingCopyManager;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIPlugin;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.wst.common.frameworks.internal.SaveFailedException;

/**
 * Insert the type's description here. Creation date: (4/25/2001 7:05:36 PM)
 * 
 * @author: Administrator
 */
public class WTPUIWorkingCopyManager extends WTPWorkingCopyManager {
    private IWorkingCopyManager javaWorkingCopyManager;
    private ICompilationUnitDocumentProvider cuDocumentProvider;
    private HashMap editorInputs;
    private CoreException lastError;

    /**
     * WTPUIWorkingCopyManager constructor comment.
     */
    public WTPUIWorkingCopyManager() {
        super();
        cuDocumentProvider = JavaPlugin.getDefault().getCompilationUnitDocumentProvider();
        javaWorkingCopyManager = JavaUI.getWorkingCopyManager();
    }

    protected void syncConnect(final IEditorInput input, final ICompilationUnit cu) throws CoreException {
        Display d = Display.getCurrent();
        if (d != null) {
            lastError = null;
            d.syncExec(new Runnable() {
                public void run() {
                    try {
                        connect(input, cu);
                    } catch (CoreException e) {
                        lastError = e;
                    }
                }
            });
        } else
            connect(input, cu);
        if (lastError != null)
            throw lastError;
    }

    /**
     * Connect the CompilationUnitDocumentProvider to the
     * 
     * @input and connect the annotation model from the provider to the IDocument of the
     * @input.
     */
    protected void connect(IEditorInput input, ICompilationUnit cu) throws CoreException {
        if (input != null && javaWorkingCopyManager != null && cuDocumentProvider != null) {
            javaWorkingCopyManager.connect(input);
            getEditorInputs().put(cu, input);
            IDocument doc = cuDocumentProvider.getDocument(input);
            if (doc != null && cuDocumentProvider.getAnnotationModel(input) != null)
                cuDocumentProvider.getAnnotationModel(input).connect(doc);
        }
    }

    protected void revertWorkingCopies() {
        if (getEditorInputs().isEmpty())
            return;
        Iterator it = getEditorInputs().values().iterator();
        IEditorInput input;
        while (it.hasNext()) {
            input = (IEditorInput) it.next();
            revert(input);
        }
    }

    /**
     * Disonnect the CompilationUnitDocumentProvider from the
     * 
     * @input and disconnect the annotation model from the provider from the IDocument of the
     * @input.
     */
    protected void disconnect(IEditorInput input) {
        IDocument doc = cuDocumentProvider.getDocument(input);
        cuDocumentProvider.getAnnotationModel(input).disconnect(doc);
        javaWorkingCopyManager.disconnect(input);
    }

    protected void revert(IEditorInput input) {
        try {
            cuDocumentProvider.resetDocument(input);
        } catch (CoreException e) {
            Logger.getLogger().logError(e);
        }
        IDocument doc = cuDocumentProvider.getDocument(input);
        IAnnotationModel model = cuDocumentProvider.getAnnotationModel(input);

        if (model instanceof AbstractMarkerAnnotationModel) {
            AbstractMarkerAnnotationModel markerModel = (AbstractMarkerAnnotationModel) model;
            markerModel.resetMarkers();
        }
        model.disconnect(doc);
        javaWorkingCopyManager.disconnect(input);
    }

    protected void disconnectEditorInputs() {
        Iterator it = getEditorInputs().values().iterator();
        IEditorInput input;
        while (it.hasNext()) {
            input = (IEditorInput) it.next();
            disconnect(input);
        }
    }

    protected void discardExistingCompilationUnits() {
        if (getEditorInputs().isEmpty())
            return;
        Iterator it = getEditorInputs().values().iterator();
        IEditorInput input;
        while (it.hasNext()) {
            input = (IEditorInput) it.next();
            disconnect(input);
        }
    }

    @Override
    public Set getAffectedFiles() {
        Set aSet = new HashSet();
        Iterator it = getEditorInputs().keySet().iterator();
        ICompilationUnit unit = null;
        IResource resource = null;
        while (it.hasNext()) {
            unit = (ICompilationUnit) it.next();
            if (isDirty(unit)) {
                try {
                    resource = unit.getUnderlyingResource();
                } catch (JavaModelException ignore) {
                    continue;
                }
                if (resource instanceof IFile)
                    aSet.add(resource);
            }
        }
        return aSet;
    }

    protected IEditorInput getEditorInput(ICompilationUnit cu) {
        IEditorInput input = primGetEditorInput(cu);
        if (input == null) {
            try {
                input = getEditorInput((IJavaElement) cu);
            } catch (JavaModelException e) {
                //Ignore
            }
        }
        return input;
    }

    protected IEditorInput getEditorInput(IJavaElement element) throws JavaModelException {
        IJavaElement localElement = element;
        while (localElement != null) {
            switch (localElement.getElementType()) {
            case IJavaElement.COMPILATION_UNIT: {
                ICompilationUnit cu = (ICompilationUnit) localElement;
                if (cu.isWorkingCopy())
                    cu = cu.getPrimary();
                IResource resource = cu.getUnderlyingResource();
                if (resource.getType() == IResource.FILE)
                    return new FileEditorInput((IFile) resource);
                break;
            }
            case IJavaElement.CLASS_FILE:
                return new InternalClassFileEditorInput((IClassFile) localElement);
            }
            localElement = localElement.getParent();
        }
        return null;
    }

    /**
     * Insert the method's description here. Creation date: (4/25/2001 7:30:20 PM)
     * 
     * @return java.util.HashMap
     */
    protected java.util.HashMap getEditorInputs() {
        if (editorInputs == null)
            editorInputs = new HashMap(20);
        return editorInputs;
    }

    /**
     * Returns the working copy remembered for the compilation unit encoded in the given editor
     * input. Does not connect the edit model to the working copy.
     * 
     * @param input
     *            ICompilationUnit
     * @return the working copy of the compilation unit, or <code>null</code> if the input does
     *         not encode an editor input, or if there is no remembered working copy for this
     *         compilation unit
     */
    @Override
    public org.eclipse.jdt.core.ICompilationUnit getExistingWorkingCopy(ICompilationUnit cu) throws CoreException {
        if (cu == null || cu.isWorkingCopy()) {
            return cu;
        }
        ICompilationUnit newCU = super.getExistingWorkingCopy(cu);
        if (newCU != null)
            return newCU;
        IEditorInput editorInput = getEditorInput(cu);
        return javaWorkingCopyManager.getWorkingCopy(editorInput);
    }

    /**
     * Returns the working copy remembered for the compilation unit.
     * 
     * @param input
     *            ICompilationUnit
     * @return the working copy of the compilation unit, or <code>null</code> if there is no
     *         remembered working copy for this compilation unit
     */
    @Override
    public org.eclipse.jdt.core.ICompilationUnit getWorkingCopy(ICompilationUnit cu, boolean forNewCU)
            throws org.eclipse.core.runtime.CoreException {
        if (forNewCU)
            return super.getWorkingCopy(cu, forNewCU);
        return primGetWorkingCopy(cu);
    }

    public boolean isDirty(ICompilationUnit cu) {
        if (cu == null)
            return false;
        IDocumentProvider p = cuDocumentProvider;
        return p == null ? false : p.canSaveDocument(getEditorInput(cu));
    }

    /**
     * mustSaveDocument method comment.
     */
    public boolean isSaveNeeded() {
        Iterator it = getEditorInputs().entrySet().iterator();
        while (it.hasNext()) {
            if (cuDocumentProvider.mustSaveDocument(it.next()))
                return true;
        }
        return false;
    }

    @Override
    protected void primDispose() {
        super.primDispose();
        discardExistingCompilationUnits();
        editorInputs = null;
        javaWorkingCopyManager = null;
    }

    @Override
    protected void primRevert() {
        super.primRevert();
        revertWorkingCopies();
        editorInputs = null;
        javaWorkingCopyManager = null;
    }

    protected IEditorInput primGetEditorInput(ICompilationUnit cu) {
        return (IEditorInput) getEditorInputs().get(cu);
    }

    /**
     * Returns the working copy remembered for the compilation unit encoded in the given editor
     * input.
     * 
     * @param input
     *            ICompilationUnit
     * @return the working copy of the compilation unit, or <code>null</code> if the input does
     *         not encode an editor input, or if there is no remembered working copy for this
     *         compilation unit
     */
    @Override
    protected org.eclipse.jdt.core.ICompilationUnit primGetWorkingCopy(ICompilationUnit cu) throws CoreException {
        if (cu == null) {
            return cu;
        }
        ICompilationUnit primary = cu.getPrimary();
        ICompilationUnit newCU = getNewCompilationUnitWorkingCopy(primary);
        if (newCU != null)
            return newCU;
        IEditorInput editorInput = primGetEditorInput(primary);
        if (editorInput == null) {
            editorInput = getEditorInput(cu);
            syncConnect(editorInput, cu);
        }
        if (cu.isWorkingCopy())
            return cu;
        return javaWorkingCopyManager.getWorkingCopy(editorInput);
    }

    /**
     * This will save all of the referenced CompilationUnits to be saved.
     */
    @Override
    protected void primSaveCompilationUnits(org.eclipse.core.runtime.IProgressMonitor monitor) {
        super.primSaveCompilationUnits(null);
        saveExistingCompilationUnits(monitor);
    }

    protected void primSaveDocument(IEditorInput input, IDocument doc, IProgressMonitor monitor)
            throws CoreException {
        try {
            cuDocumentProvider.saveDocument(monitor, input, doc, true); // overwrite if needed
        } catch (CoreException ex) {
            if (!isFailedWriteFileFailure(ex))
                throw ex;
            IResource resource = (IResource) input.getAdapter(IRESOURCE_CLASS);
            if (resource == null || resource.getType() != IResource.FILE
                    || !resource.getResourceAttributes().isReadOnly())
                throw ex;

            if (getSaveHandler().shouldContinueAndMakeFileEditable((IFile) resource))
                cuDocumentProvider.saveDocument(monitor, input, doc, false);
            else
                throw ex;
        }
    }

    protected void saveDocument(IEditorInput input, IProgressMonitor monitor) {
        IDocument doc = cuDocumentProvider.getDocument(input);
        boolean canSave = cuDocumentProvider.canSaveDocument(input);
        try {
            if (canSave) {
                ICompilationUnit unit = javaWorkingCopyManager.getWorkingCopy(input);
                synchronized (unit) {
                    cuDocumentProvider.aboutToChange(input);
                    primSaveDocument(input, doc, monitor);
                }
            }
        } catch (CoreException e) {
            J2EEUIPlugin.logError(e);
            throw new SaveFailedException(e);
        } finally {
            if (canSave)
                cuDocumentProvider.changed(input);
        }
    }

    /**
     * This will save all of the referenced CompilationUnits to be saved.
     */
    protected void saveExistingCompilationUnits(org.eclipse.core.runtime.IProgressMonitor monitor) {
        if (getEditorInputs().isEmpty())
            return;
        if (!validateState()) {
            if (monitor != null)
                monitor.setCanceled(true);
            return;
        }
        Iterator it = getEditorInputs().entrySet().iterator();
        Map.Entry entry;
        //   ICompilationUnit cu;
        IEditorInput input;
        try {
            while (it.hasNext()) {
                entry = (Map.Entry) it.next();
                //         cu = (ICompilationUnit) entry.getKey();
                input = (IEditorInput) entry.getValue();
                try {
                    saveDocument(input, null);
                } finally {
                    disconnect(input);
                }
            }
        } finally {
            getEditorInputs().clear();
        }
    }

    /**
     * Call validateEdit for all read only IFiles corresponding to each WorkingCopy.
     * 
     * @return boolean
     */
    private boolean validateState() {
        List readOnlyFiles = getReadOnlyModifiedFiles();
        if (readOnlyFiles != null && !readOnlyFiles.isEmpty()) {
            IFile[] files = new IFile[readOnlyFiles.size()];
            readOnlyFiles.toArray(files);
            IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            Object ctx = win == null ? null : win.getShell();
            IStatus status = ResourcesPlugin.getWorkspace().validateEdit(files, ctx);
            return status.isOK();
        }
        return true;
    }

    private List getReadOnlyModifiedFiles() {
        List readOnlyFiles = null;
        IFile readOnlyFile = null;
        Iterator it = getEditorInputs().entrySet().iterator();
        Map.Entry entry;
        //   ICompilationUnit cu;
        IEditorInput input;
        IDocumentProvider docProv = cuDocumentProvider;
        while (it.hasNext()) {
            readOnlyFile = null;
            entry = (Map.Entry) it.next();
            //      cu = (ICompilationUnit) entry.getKey();
            input = (IEditorInput) entry.getValue();
            if (docProv.canSaveDocument(input))
                readOnlyFile = getReadOnlyFile(input);
            if (readOnlyFile != null) {
                if (readOnlyFiles == null)
                    readOnlyFiles = new ArrayList();
                readOnlyFiles.add(readOnlyFile);
            }
        }
        return readOnlyFiles;
    }

    private IFile getReadOnlyFile(IEditorInput input) {
        if (input instanceof IFileEditorInput) {
            IFileEditorInput finput = (IFileEditorInput) input;
            IFile file = finput.getFile();
            if (file.isReadOnly())
                return file;
        }
        return null;
    }

    @Override
    protected void addDeletedCompilationUnit(ICompilationUnit cu) {
        IEditorInput input = primGetEditorInput(cu);
        if (input != null)
            disconnect(input);
        getEditorInputs().remove(cu);
        super.addDeletedCompilationUnit(cu);
    }

    /**
     * @see com.ibm.etools.j2ee.workbench.IJ2EEWorkingCopyManager#hasWorkingCopies()
     */
    @Override
    public boolean hasWorkingCopies() {
        return super.hasWorkingCopies() || (editorInputs != null && !editorInputs.isEmpty());
    }

}