📄 pythonmodelprovider.java
字号:
/*
* Created on Oct 7, 2006
* @author Fabio
*/
package org.python.pydev.navigator;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.IPipelinedTreeContentProvider;
import org.eclipse.ui.navigator.PipelinedShapeModification;
import org.eclipse.ui.navigator.PipelinedViewerUpdate;
import org.python.pydev.core.structure.FastStack;
import org.python.pydev.navigator.elements.IWrappedResource;
import org.python.pydev.navigator.elements.PythonFile;
import org.python.pydev.navigator.elements.PythonFolder;
import org.python.pydev.navigator.elements.PythonProjectSourceFolder;
import org.python.pydev.navigator.elements.PythonResource;
import org.python.pydev.navigator.elements.PythonSourceFolder;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.plugin.nature.PythonNature;
/**
* This is the Model provider for python elements.
*
* It intercepts the adds/removes and changes the original elements for elements
* that actually reflect the python model (with source folder, etc).
*
*
* Tests for package explorer:
* 1. Start eclipse with a file deep in the structure and without having anything expanded in the tree, make a 'show in'
*
* @author Fabio
*/
public class PythonModelProvider extends PythonBaseModelProvider implements IPipelinedTreeContentProvider {
private static final boolean DEBUG = false;
/**
* This method basically replaces all the elements for other resource elements
* or for wrapped elements.
*
* @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#getPipelinedChildren(java.lang.Object, java.util.Set)
*/
@SuppressWarnings("unchecked")
public void getPipelinedChildren(Object parent, Set currentElements) {
if(DEBUG){
System.out.println("getPipelinedChildren");
}
Object[] children = getChildren(parent);
currentElements.clear();
currentElements.addAll(Arrays.asList(children));
}
/**
* This method basically replaces all the elements for other resource elements
* or for wrapped elements.
*
* @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#getPipelinedElements(java.lang.Object, java.util.Set)
*/
@SuppressWarnings("unchecked")
public void getPipelinedElements(Object input, Set currentElements) {
if(DEBUG){
System.out.println("getPipelinedElements");
}
Object[] children = getElements(input);
currentElements.clear();
currentElements.addAll(Arrays.asList(children));
}
/**
* This method basically get the actual parent for the resource or the parent
* for a wrapped element (which may be a resource or a wrapped resource).
*
* @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#getPipelinedParent(java.lang.Object, java.lang.Object)
*/
public Object getPipelinedParent(Object object, Object aSuggestedParent) {
if(DEBUG){
System.out.println("getPipelinedParent");
}
return getParent(object);
}
/**
* This method intercepts some addition to the tree and converts its elements to python
* elements.
*
* @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#interceptAdd(org.eclipse.ui.navigator.PipelinedShapeModification)
*/
public PipelinedShapeModification interceptAdd(PipelinedShapeModification addModification) {
if(DEBUG){
System.out.println("interceptAdd");
}
convertToPythonElementsAddOrRemove(addModification, true);
return addModification;
}
public boolean interceptRefresh(PipelinedViewerUpdate refreshSynchronization) {
if(DEBUG){
System.out.println("interceptRefresh");
}
return convertToPythonElementsUpdateOrRefresh(refreshSynchronization.getRefreshTargets());
}
public PipelinedShapeModification interceptRemove(PipelinedShapeModification removeModification) {
if(DEBUG){
System.out.println("interceptRemove");
}
convertToPythonElementsAddOrRemove(removeModification, false);
return removeModification;
}
public boolean interceptUpdate(PipelinedViewerUpdate updateSynchronization) {
if(DEBUG){
debug("Before interceptUpdate", updateSynchronization);
}
boolean ret = convertToPythonElementsUpdateOrRefresh(updateSynchronization.getRefreshTargets());
if(DEBUG){
debug("After interceptUpdate", updateSynchronization);
}
return ret;
}
/**
* Helper for debugging the things we have in an update
*/
private void debug(String desc, PipelinedViewerUpdate updateSynchronization) {
System.out.println("\nDesc:"+desc);
System.out.println("Refresh targets:");
for(Object o:updateSynchronization.getRefreshTargets()){
System.out.println(o);
}
}
/**
* Helper for debugging the things we have in a modification
*/
private void debug(String desc, PipelinedShapeModification modification) {
System.out.println("\nDesc:"+desc);
Object parent = modification.getParent();
System.out.println("Parent:"+parent);
System.out.println("Children:");
for(Object o:modification.getChildren()){
System.out.println(o);
}
}
public void init(ICommonContentExtensionSite aConfig) {
}
/**
* This is the function that is responsible for restoring the paths in the tree.
*/
public void restoreState(IMemento memento) {
new PyPackageStateSaver(this, viewer, memento).restoreState();
}
/**
* This is the function that is responsible for saving the paths in the tree.
*/
public void saveState(IMemento memento) {
new PyPackageStateSaver(this, viewer, memento).saveState();
}
/**
* Converts the shape modification to use Python elements.
*
* @param modification: the shape modification to convert
* @param isAdd: boolean indicating whether this convertion is happening in an add operation
*/
private void convertToPythonElementsAddOrRemove(PipelinedShapeModification modification, boolean isAdd) {
if(DEBUG){
debug("Before", modification);
}
Object parent = modification.getParent();
if (parent instanceof IContainer) {
IContainer parentContainer = (IContainer) parent;
Object pythonParent = getResourceInPythonModel(parentContainer, true);
if (pythonParent instanceof IWrappedResource) {
IWrappedResource parentResource = (IWrappedResource) pythonParent;
modification.setParent(parentResource);
wrapChildren(parentResource, parentResource.getSourceFolder(), modification.getChildren(), isAdd);
}else if(pythonParent == null){
Object parentInWrap = parentContainer;
PythonSourceFolder sourceFolderInWrap = null;
//this may happen when a source folder is added or some element that still doesn't have it's parent in the model...
//so, we have to get the parent's parent until we actually 'know' that it is not in the model (or until we run
//out of parents to try)
//the case in which we reproduce this is Test 1 (described in the class)
FastStack<Object> found = new FastStack<Object>();
while(true){
//add the current to the found
found.push(parentContainer);
parentContainer = parentContainer.getParent();
if(parentContainer == null){
break;
}
if(parentContainer instanceof IProject){
//we got to the project without finding any part of a python model already there, so, let's see
//if any of the parts was actually a source folder (that was still not added)
tryCreateModelFromProject((IProject) parentContainer, found);
//and now, if it was created, try to convert it to the python model (without any further add)
convertToPythonElementsUpdateOrRefresh(modification.getChildren());
return;
}
Object p = getResourceInPythonModel(parentContainer, true);
if(p instanceof IWrappedResource){
IWrappedResource wrappedResource = (IWrappedResource) p;
sourceFolderInWrap = wrappedResource.getSourceFolder();
while(found.size() > 0){
Object f = found.pop();
//creating is enough to add it to the model
if(f instanceof IFile){
wrappedResource = new PythonFile(wrappedResource, (IFile)f, sourceFolderInWrap);
}else if(f instanceof IFolder){
wrappedResource = new PythonFolder(wrappedResource, (IFolder)f, sourceFolderInWrap);
}
}
parentInWrap = wrappedResource;
break;
}
}
wrapChildren(parentInWrap, sourceFolderInWrap, modification.getChildren(), isAdd);
}
}else if(parent == null){
wrapChildren(null, null, modification.getChildren(), isAdd);
}
if(DEBUG){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -