org.eclipse.jst.common.jdt.internal.integration.WTPWorkingCopyManager.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.common.jdt.internal.integration.WTPWorkingCopyManager.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;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.common.frameworks.CommonFrameworksPlugin;
import org.eclipse.wst.common.frameworks.internal.ISaveHandler;
import org.eclipse.wst.common.frameworks.internal.SaveFailedException;
import org.eclipse.wst.common.frameworks.internal.SaveHandlerHeadless;
import org.eclipse.wst.common.frameworks.internal.SaveHandlerRegister;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;

/**
 * Insert the type's description here. Creation date: (4/27/2001 4:14:30 PM)
 * 
 * @author: Administrator
 */
public class WTPWorkingCopyManager implements WorkingCopyManager {

    //New CUs that will need to be deleted upon dispose
    private List originalNewCompilationUnits;
    //New CUs that were created that need saved immediately (after each gen)
    private List needsSavingCompilationUnits;
    //A complete list of new CUs that is only cleared on save and dispose
    private List newCompilationUnits;
    private HashMap deletedCompilationUnits;
    protected static final Class IRESOURCE_CLASS = IResource.class;

    /**
     * WTPWorkingCopyManager constructor comment.
     */
    public WTPWorkingCopyManager() {
        super();
    }

    protected void addDeletedCompilationUnit(ICompilationUnit cu) {
        getNeedsSavingCompilationUnits().remove(cu);
        if (!getOriginalNewCompilationUnits().contains(cu) && !getDeletedCompilationUnits().containsKey(cu))
            primAddDeletedCompilationUnit(cu);
        getOriginalNewCompilationUnits().remove(cu);
    }

    protected void addNewCompilationUnit(ICompilationUnit cu, ICompilationUnit workingCopy) {
        getNewCompilationUnits().add(cu);
        getNeedsSavingCompilationUnits().add(workingCopy);
        if (!getDeletedCompilationUnits().containsKey(cu))
            getOriginalNewCompilationUnits().add(cu);
    }

    /**
     * This will save all of the new CompilationUnits to be saved.
     */
    protected void commitWorkingCopy(ICompilationUnit wc, IProgressMonitor monitor) {
        try {
            try {
                wc.commitWorkingCopy(false, monitor);
            } catch (JavaModelException e) {
                if (isFailedWriteFileFailure(e) && shouldSaveReadOnly(wc))
                    wc.commitWorkingCopy(false, monitor);
                else
                    throw e;
            }
        } catch (JavaModelException e) {
            org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(e);
            throw new SaveFailedException(e);
        } finally {
            try {
                wc.discardWorkingCopy();
            } catch (JavaModelException e1) {
                org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(e1);
                throw new SaveFailedException(e1);
            }
        }
    }

    /**
     * This will delete
     * 
     * @cu from the workbench and fix the internal references for this working copy manager.
     */
    public void delete(final ICompilationUnit cu, final IProgressMonitor monitor) {
        ICompilationUnit localCU = cu;
        if (localCU.isWorkingCopy())
            localCU = localCU.getPrimary();
        addDeletedCompilationUnit(localCU);
        try {
            localCU.delete(false, monitor);
        } catch (JavaModelException e) {
            if (e.getStatus().getCode() != org.eclipse.jdt.core.IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST)
                org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(e);
        }
    }

    protected void discardOriginalNewCompilationUnits() {
        if (getOriginalNewCompilationUnits().isEmpty())
            return;
        List cus = getOriginalNewCompilationUnits();
        ICompilationUnit cu;
        ICompilationUnit wc = null;
        for (int i = 0; i < cus.size(); i++) {
            cu = (ICompilationUnit) cus.get(i);
            if (cu.isWorkingCopy()) {
                wc = cu;
                cu = wc.getPrimary();
            }
            primDelete(cu);
            if (wc != null)
                try {
                    wc.discardWorkingCopy();
                } catch (JavaModelException e) {
                    Logger.getLogger().logError(e);
                }
        }
    }

    public void dispose() {
        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
            public void run(IProgressMonitor aMonitor) {
                primDispose();
            }
        };
        try {
            if (!WTPCommonPlugin.getWorkspace().isTreeLocked()) {
                WTPCommonPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, null);
            } else {
                runnable.run(null);
            }
        } catch (CoreException e) {
            CommonFrameworksPlugin.logError(e);
        }
    }

    public void revert() {
        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
            public void run(IProgressMonitor aMonitor) {
                primRevert();
            }
        };
        runOperation(runnable, null, true);
    }

    public Set getAffectedFiles() {
        return Collections.EMPTY_SET;
    }

    /**
     * Insert the method's description here. Creation date: (7/11/2001 6:43:37 PM)
     * 
     * @return java.util.HashMap
     */
    protected HashMap getDeletedCompilationUnits() {
        if (deletedCompilationUnits == null)
            deletedCompilationUnits = new HashMap();
        return deletedCompilationUnits;
    }

    /**
     * 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
     */
    public org.eclipse.jdt.core.ICompilationUnit getExistingWorkingCopy(ICompilationUnit cu) throws CoreException {
        ICompilationUnit newCU = getNewCompilationUnitWorkingCopy(cu);
        if (newCU != null)
            return newCU;
        return null;
    }

    /**
     * Insert the method's description here. Creation date: (7/19/2001 11:00:19 AM)
     * 
     * @return java.util.List
     */
    protected java.util.List getNeedsSavingCompilationUnits() {
        if (needsSavingCompilationUnits == null)
            needsSavingCompilationUnits = new ArrayList();
        return needsSavingCompilationUnits;
    }

    /**
     * Insert the method's description here. Creation date: (4/26/2001 3:49:05 PM)
     * 
     * @return java.util.List
     */
    protected java.util.List getNewCompilationUnits() {
        if (newCompilationUnits == null)
            newCompilationUnits = new ArrayList();
        return newCompilationUnits;
    }

    /**
     * It is possible that we have already created this CompilationUnit and its working copy. If
     * this is the case, return our new working copy and do not create a new one.
     */
    protected ICompilationUnit getNewCompilationUnitWorkingCopy(ICompilationUnit cu) {
        if (hasNewCompilationUnit(cu)) {
            List list = getNeedsSavingCompilationUnits();
            ICompilationUnit copy;
            for (int i = 0; i < list.size(); i++) {
                copy = (ICompilationUnit) list.get(i);
                if (cu.equals(copy.getPrimary()))
                    return copy;
            }
        }
        return null;
    }

    /**
     * Insert the method's description here. Creation date: (4/26/2001 3:49:05 PM)
     * 
     * @return java.util.List
     */
    protected java.util.List getOriginalNewCompilationUnits() {
        if (originalNewCompilationUnits == null)
            originalNewCompilationUnits = new ArrayList();
        return originalNewCompilationUnits;
    }

    /**
     * Return the IPackageFragment for the given ICompilationUnit.
     */
    protected IPackageFragment getPackageFragment(ICompilationUnit cu) {
        if (cu == null)
            return null;
        IJavaElement parent = cu;
        int elementType = cu.getElementType();
        while (parent != null && elementType != IJavaElement.PACKAGE_FRAGMENT) {
            parent = parent.getParent();
            if (parent != null)
                elementType = parent.getElementType();
            else
                elementType = -1;
        }
        return (IPackageFragment) parent;
    }

    protected ISaveHandler getSaveHandler() {
        return SaveHandlerRegister.getSaveHandler();
    }

    /**
     * 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
     */
    public ICompilationUnit getWorkingCopy(ICompilationUnit cu, boolean forNewCU)
            throws org.eclipse.core.runtime.CoreException {
        if (cu == null || cu.isWorkingCopy())
            return cu;
        ICompilationUnit newCU = getNewCompilationUnitWorkingCopy(cu);
        if (newCU != null)
            return newCU;
        ICompilationUnit workingCopy = cu.getWorkingCopy(null);
        addNewCompilationUnit(cu, workingCopy);
        return workingCopy;
    }

    /**
     * Has a new compilation unit already been created.
     */
    protected boolean hasNewCompilationUnit(ICompilationUnit cu) {
        return getNewCompilationUnits().contains(cu);
    }

    protected boolean isFailedWriteFileFailure(Exception ex) {
        return SaveHandlerHeadless.isFailedWriteFileFailure(ex);
    }

    protected void primAddDeletedCompilationUnit(ICompilationUnit cu) {
        if (cu == null)
            return;
        Object[] info = new Object[2];
        info[0] = getPackageFragment(cu);
        try {
            info[1] = cu.getSource();
        } catch (JavaModelException e) {
            info[1] = null;
        }
        getDeletedCompilationUnits().put(cu, info);
    }

    // This is an internal delete call.
    protected void primDelete(ICompilationUnit cu) {
        try {
            if (cu.exists())
                cu.delete(true, new org.eclipse.core.runtime.NullProgressMonitor());
        } catch (JavaModelException e) {
            org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(e);
            //What to do here?
        }
    }

    protected void primDispose() {
        discardOriginalNewCompilationUnits();
        reviveDeletedCompilationUnits();
        newCompilationUnits = null;
        needsSavingCompilationUnits = null;
        originalNewCompilationUnits = null;
        deletedCompilationUnits = null;
    }

    protected void primRevert() {
        discardOriginalNewCompilationUnits();
        reviveDeletedCompilationUnits();
        newCompilationUnits = null;
        needsSavingCompilationUnits = null;
        originalNewCompilationUnits = null;
        deletedCompilationUnits = null;
    }

    /**
     * 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
     */
    protected ICompilationUnit primGetWorkingCopy(ICompilationUnit cu) throws CoreException {
        return null;
    }

    /**
     * This will save all of the referenced CompilationUnits to be saved.
     */
    protected void primSaveCompilationUnits(org.eclipse.core.runtime.IProgressMonitor monitor) {
        saveNewCompilationUnits(monitor);
        getDeletedCompilationUnits().clear();
    }

    /**
     * This will save all of the new CompilationUnits to be saved.
     */
    protected void primSaveOnlyNewCompilationUnits(org.eclipse.core.runtime.IProgressMonitor monitor) {
        List cus = getNeedsSavingCompilationUnits();
        ICompilationUnit wc;
        for (int i = 0; i < cus.size(); i++) {
            wc = (ICompilationUnit) cus.get(i);
            commitWorkingCopy(wc, monitor);
        }
        cus.clear();
    }

    protected void removeDeletedCompilationUnit(ICompilationUnit cu) {
        if (getDeletedCompilationUnits().remove(cu) != null) {
            if (cu.isWorkingCopy()) {
                ICompilationUnit original, nextCU, testCU;
                original = cu.getPrimary();
                Set cus = getDeletedCompilationUnits().keySet();
                Iterator it = cus.iterator();
                while (it.hasNext()) {
                    nextCU = (ICompilationUnit) it.next();
                    testCU = nextCU.isWorkingCopy() ? (ICompilationUnit) nextCU.getPrimary() : nextCU;
                    if (testCU.equals(original)) {
                        cus.remove(nextCU);
                        return;
                    }
                }
            }
        }
    }

    protected void reviveDeletedCompilationUnit(ICompilationUnit cu, Object[] info, IProgressMonitor pm) {
        if (cu.getJavaProject().isOpen()) {
            if (info[0] != null && info[1] != null) {
                String typeName = cu.getElementName();
                IPackageFragment pack = (IPackageFragment) info[0];
                String source = (String) info[1];
                try {
                    ICompilationUnit existingCU = pack.getCompilationUnit(typeName);
                    if (existingCU.exists() && getNewCompilationUnits().contains(existingCU))
                        existingCU.delete(false, pm);
                    pack.createCompilationUnit(typeName, source, false, pm);
                } catch (JavaModelException e) {
                    org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(e);
                }
            }
        }
    }

    protected void reviveDeletedCompilationUnits() {
        if (getDeletedCompilationUnits().isEmpty())
            return;

        IProgressMonitor pm = new org.eclipse.core.runtime.NullProgressMonitor();
        Iterator it = getDeletedCompilationUnits().entrySet().iterator();
        Map.Entry entry;
        ICompilationUnit cu;
        Object[] info;
        while (it.hasNext()) {
            entry = (Map.Entry) it.next();
            cu = (ICompilationUnit) entry.getKey();
            info = (Object[]) entry.getValue();
            reviveDeletedCompilationUnit(cu, info, pm);
        }

    }

    protected void runOperation(IWorkspaceRunnable aRunnable, IProgressMonitor monitor, boolean validate) {
        primRunOperation(aRunnable, monitor);

        // TODO Break the validator depedency
        //   if (validate)
        //      primRunOperation(aRunnable, monitor);
        //   else {
        //      IProject proj = getValidationProject();
        //         
        //      ValidatorManager mgr = ValidatorManager.getManager();
        //      boolean disableValidators = proj != null;
        //      boolean wasSuspended = false;
        //      if (disableValidators) {
        //         wasSuspended = mgr.isSuspended(proj);
        //         if (!wasSuspended)
        //            mgr.suspendValidation(proj, true);
        //      }
        //      try {
        //         primRunOperation(aRunnable, monitor);
        //      } finally {
        //         if (disableValidators && !wasSuspended)
        //            mgr.suspendValidation(proj, false);
        //      }
        //   }
    }

    protected void primRunOperation(IWorkspaceRunnable aRunnable, IProgressMonitor monitor) {

        if (aRunnable != null) {
            //if (workspace.isTreeLocked())
            //Logger.getLogger().logTrace(ResourceHandler.getString("Cannot_run_J2EEUIWorkingCo_ERROR_"));
            // //$NON-NLS-1$ = "Cannot run J2EEUIWorkingCopyManager operation because the Workspace
            // tree is locked."
            //else {
            if (!WTPCommonPlugin.getWorkspace().isTreeLocked()) {
                try {
                    WTPCommonPlugin.getWorkspace().run(aRunnable, monitor);
                } catch (CoreException e) {
                    throw new SaveFailedException(e);
                }
            }
        }
    }

    /**
     * This will save all of the referenced CompilationUnits to be saved.
     */
    public void saveCompilationUnits(org.eclipse.core.runtime.IProgressMonitor monitor) {
        getSaveHandler().access();
        try {
            IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
                public void run(IProgressMonitor aMonitor) {
                    primSaveCompilationUnits(aMonitor);
                }
            };
            runOperation(runnable, monitor, true);
        } catch (SaveFailedException ex) {
            getSaveHandler().handleSaveFailed(ex, monitor);
        } finally {
            getSaveHandler().release();
        }
    }

    /**
     * This will save all of the referenced CompilationUnits to be saved.
     */
    protected void saveNewCompilationUnits(IProgressMonitor monitor) {
        primSaveOnlyNewCompilationUnits(monitor);
        getOriginalNewCompilationUnits().clear();
        getNewCompilationUnits().clear();
    }

    /**
     * This will save all of the new CompilationUnits to be saved.
     */
    public void saveOnlyNewCompilationUnits(org.eclipse.core.runtime.IProgressMonitor monitor) {
        getSaveHandler().access();
        try {
            IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
                public void run(IProgressMonitor aMonitor) {
                    primSaveOnlyNewCompilationUnits(aMonitor);
                }
            };
            runOperation(runnable, monitor, false);
        } catch (SaveFailedException ex) {
            getSaveHandler().handleSaveFailed(ex, monitor);
        } finally {
            getSaveHandler().release();
        }
    }

    protected boolean shouldSaveReadOnly(ICompilationUnit wc) {
        IResource resource = null;

        resource = (IResource) wc.getPrimary().getAdapter(IRESOURCE_CLASS);

        if (resource == null || resource.getType() != IResource.FILE
                || !resource.getResourceAttributes().isReadOnly())
            return false;

        return getSaveHandler().shouldContinueAndMakeFileEditable((IFile) resource);
    }

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

}