FileDocCategorySizeDatePackage
ResourceManager.javaAPI DocAndroid 1.5 API19705Wed May 06 22:41:10 BST 2009com.android.ide.eclipse.editors.resources.manager

ResourceManager

public final class ResourceManager extends Object implements com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener, com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFolderListener, com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener

Fields Summary
private static final ResourceManager
sThis
private final com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier[]
mQualifiers
List of the qualifier object helping for the parsing of folder names
private final HashMap
mMap
Map associating project resource with project objects.
Constructors Summary
ResourceManager()
Private constructor to enforce singleton design.

        // get the default qualifiers.
        FolderConfiguration defaultConfig = new FolderConfiguration();
        defaultConfig.createDefault();
        mQualifiers = defaultConfig.getQualifiers();
    
Methods Summary
private voidcreateProject(org.eclipse.core.resources.IProject project)
Initial project parsing to gather resource info.

param
project

        if (project.isOpen()) {
            try {
                if (project.hasNature(AndroidConstants.NATURE) == false) {
                    return;
                }
            } catch (CoreException e1) {
                // can't check the nature of the project? ignore it.
                return;
            }
            
            IFolder resourceFolder = project.getFolder(SdkConstants.FD_RESOURCES);
            
            ProjectResources projectResources = mMap.get(project);
            if (projectResources == null) {
                projectResources = new ProjectResources(false /* isFrameworkRepository */);
                mMap.put(project, projectResources);
            }
            
            if (resourceFolder != null && resourceFolder.exists()) {
                try {
                    IResource[] resources = resourceFolder.members();
                    
                    for (IResource res : resources) {
                        if (res.getType() == IResource.FOLDER) {
                            IFolder folder = (IFolder)res;
                            ResourceFolder resFolder = processFolder(new IFolderWrapper(folder),
                                    projectResources);
                            
                            if (resFolder != null) {
                                // now we process the content of the folder
                                IResource[] files = folder.members();
                                
                                for (IResource fileRes : files) {
                                    if (fileRes.getType() == IResource.FILE) {
                                        IFile file = (IFile)fileRes;
                                        
                                        processFile(new IFileWrapper(file), resFolder);
                                    }
                                }
                            }
                        }
                    }
                } catch (CoreException e) {
                    // This happens if the project is closed or if the folder doesn't exist.
                    // Since we already test for that, we can ignore this exception.
                }
            }
        }
    
public voidfileChanged(org.eclipse.core.resources.IFile file, org.eclipse.core.resources.IMarkerDelta[] markerDeltas, int kind)

        ProjectResources resources;
        
        final IProject project = file.getProject();
        
        try {
            if (project.hasNature(AndroidConstants.NATURE) == false) {
                return;
            }
        } catch (CoreException e) {
            // can't get the project nature? return!
            return;
        }
        
        switch (kind) {
            case IResourceDelta.ADDED:
                // checks if the file is under res/something.
                IPath path = file.getFullPath();
                
                if (path.segmentCount() == 4) {
                    if (isInResFolder(path)) {
                        // get the project and its resources
                        resources = mMap.get(project);
        
                        IContainer container = file.getParent();
                        if (container instanceof IFolder && resources != null) {
                            
                            ResourceFolder folder = resources.getResourceFolder((IFolder)container);
                            
                            if (folder != null) {
                                processFile(new IFileWrapper(file), folder);
                            }
                        }
                    }
                }
                break;
            case IResourceDelta.CHANGED:
                // try to find a matching ResourceFile
                resources = mMap.get(project);
                if (resources != null) {
                    IContainer container = file.getParent();
                    if (container instanceof IFolder) {
                        ResourceFolder resFolder = resources.getResourceFolder((IFolder)container);
                        
                        // we get the delete on the folder before the file, so it is possible
                        // the associated ResourceFolder doesn't exist anymore.
                        if (resFolder != null) {
                            // get the resourceFile, and touch it.
                            ResourceFile resFile = resFolder.getFile(file);
                            if (resFile != null) {
                                resFile.touch();
                            }
                        }
                    }
                }
                break;
            case IResourceDelta.REMOVED:
                // try to find a matching ResourceFile
                resources = mMap.get(project);
                if (resources != null) {
                    IContainer container = file.getParent();
                    if (container instanceof IFolder) {
                        ResourceFolder resFolder = resources.getResourceFolder((IFolder)container);
                        
                        // we get the delete on the folder before the file, so it is possible
                        // the associated ResourceFolder doesn't exist anymore.
                        if (resFolder != null) {
                            // remove the file
                            resFolder.removeFile(file);
                        }
                    }
                }
                break;
        }
    
public voidfolderChanged(org.eclipse.core.resources.IFolder folder, int kind)
Processes folder event.

        ProjectResources resources;
        
        final IProject project = folder.getProject();
        
        try {
            if (project.hasNature(AndroidConstants.NATURE) == false) {
                return;
            }
        } catch (CoreException e) {
            // can't get the project nature? return!
            return;
        }
        
        switch (kind) {
            case IResourceDelta.ADDED:
                // checks if the folder is under res.
                IPath path = folder.getFullPath();
                
                // the path will be project/res/<something>
                if (path.segmentCount() == 3) {
                    if (isInResFolder(path)) {
                        // get the project and its resource object.
                        resources = mMap.get(project);
                        
                        // if it doesn't exist, we create it.
                        if (resources == null) {
                            resources = new ProjectResources(false /* isFrameworkRepository */);
                            mMap.put(project, resources);
                        }

                        processFolder(new IFolderWrapper(folder), resources);
                    }
                }
                break;
            case IResourceDelta.CHANGED:
                resources = mMap.get(folder.getProject());
                if (resources != null) {
                    ResourceFolder resFolder = resources.getResourceFolder(folder);
                    if (resFolder != null) {
                        resFolder.touch();
                    }
                }
                break;
            case IResourceDelta.REMOVED:
                resources = mMap.get(folder.getProject());
                if (resources != null) {
                    // lets get the folder type
                    ResourceFolderType type = ResourceFolderType.getFolderType(folder.getName());

                    resources.removeFolder(type, folder);
                }
                break;
        }
    
public com.android.ide.eclipse.editors.resources.configurations.FolderConfigurationgetConfig(java.lang.String[] folderSegments)
Creates a {@link FolderConfiguration} matching the folder segments.

param
folderSegments The segments of the folder name. The first segments should contain the name of the folder
return
a FolderConfiguration object, or null if the folder name isn't valid..

        FolderConfiguration config = new FolderConfiguration();

        // we are going to loop through the segments, and match them with the first
        // available qualifier. If the segment doesn't match we try with the next qualifier.
        // Because the order of the qualifier is fixed, we do not reset the first qualifier
        // after each sucessful segment.
        // If we run out of qualifier before processing all the segments, we fail.
        
        int qualifierIndex = 0;
        int qualifierCount = mQualifiers.length;
        
        for (int i = 1 ; i < folderSegments.length; i++) {
            String seg = folderSegments[i];
            if (seg.length() > 0) {
                while (qualifierIndex < qualifierCount &&
                        mQualifiers[qualifierIndex].checkAndSet(seg, config) == false) {
                    qualifierIndex++;
                }
                
                // if we reached the end of the qualifier we didn't find a matching qualifier.
                if (qualifierIndex == qualifierCount) {
                    return null;
                }
                
            } else {
                return null;
            }
        }

        return config;
    
public static com.android.ide.eclipse.editors.resources.manager.ResourceManagergetInstance()
Returns the singleton instance.

        return sThis;
    
public ProjectResourcesgetProjectResources(org.eclipse.core.resources.IProject project)
Returns the resources of a project.

param
project The project
return
a ProjectResources object or null if none was found.

        return mMap.get(project);
    
public ResourceFoldergetResourceFolder(org.eclipse.core.resources.IFile file)
Returns the {@link ResourceFolder} for the given file or null if none exists.

        IContainer container = file.getParent();
        if (container.getType() == IResource.FOLDER) {
            IFolder parent = (IFolder)container;
            IProject project = file.getProject();
            
            ProjectResources resources = getProjectResources(project);
            if (resources != null) {
                return resources.getResourceFolder(parent);
            }
        }
        
        return null;
    
private booleanisInResFolder(org.eclipse.core.runtime.IPath path)
Returns true if the path is under /project/res/

param
path a workspace relative path
return
true if the path is under /project res/

        return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
    
public ProjectResourcesloadFrameworkResources(com.android.sdklib.IAndroidTarget androidTarget)
Loads and returns the resources for a given {@link IAndroidTarget}

param
androidTarget the target from which to load the framework resources

        String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES);
        
        File frameworkRes = new File(osResourcesPath);
        if (frameworkRes.isDirectory()) {
            ProjectResources resources = new ProjectResources(true /* isFrameworkRepository */);

            try {
                File[] files = frameworkRes.listFiles();
                for (File file : files) {
                    if (file.isDirectory()) {
                        ResourceFolder resFolder = processFolder(new FolderWrapper(file),
                                resources);
                        
                        if (resFolder != null) {
                            // now we process the content of the folder
                            File[] children = file.listFiles();
                            
                            for (File childRes : children) {
                                if (childRes.isFile()) {
                                    processFile(new FileWrapper(childRes), resFolder);
                                }
                            }
                        }
                        
                    }
                }
                
                // now that we have loaded the files, we need to force load the resources from them
                resources.loadAll();
                
                return resources;
                
            } catch (IOException e) {
                // since we test that folders are folders, and files are files, this shouldn't
                // happen. We can ignore it.
            }
        }
        
        return null;
    
private voidprocessFile(com.android.ide.eclipse.editors.resources.manager.files.IAbstractFile file, ResourceFolder folder)
Processes a file and adds it to its parent folder resource.

param
file
param
folder

        // get the type of the folder
        ResourceFolderType type = folder.getType();
        
        // look for this file if it's already been created
        ResourceFile resFile = folder.getFile(file);
        
        if (resFile != null) {
            // invalidate the file
            resFile.touch();
        } else {
            // create a ResourceFile for it.
            
            // check if that's a single or multi resource type folder. For now we define this by
            // the number of possible resource type output by files in the folder. This does
            // not make the difference between several resource types from a single file or
            // the ability to have 2 files in the same folder generating 2 different types of
            // resource. The former is handled by MultiResourceFile properly while we don't
            // handle the latter. If we were to add this behavior we'd have to change this call.
            ResourceType[] types = FolderTypeRelationship.getRelatedResourceTypes(type);
    
            if (types.length == 1) {
                resFile = new SingleResourceFile(file, folder);
            } else {
                resFile = new MultiResourceFile(file, folder);
            }
    
            // add it to the folder
            folder.addFile(resFile);
        }
    
private ResourceFolderprocessFolder(com.android.ide.eclipse.editors.resources.manager.files.IAbstractFolder folder, ProjectResources project)
Processes a folder and adds it to the list of the project resources.

param
folder the folder to process
param
project the folder's project.
return
the ConfiguredFolder created from this folder, or null if the process failed.

        // split the name of the folder in segments.
        String[] folderSegments = folder.getName().split(FolderConfiguration.QUALIFIER_SEP);

        // get the enum for the resource type.
        ResourceFolderType type = ResourceFolderType.getTypeByName(folderSegments[0]);
        
        if (type != null) {
            // get the folder configuration.
            FolderConfiguration config = getConfig(folderSegments);
            
            if (config != null) {
                ResourceFolder configuredFolder = project.add(type, config, folder);

                return configuredFolder;
            }
        }
        
        return null;
    
public voidprojectClosed(org.eclipse.core.resources.IProject project)

        mMap.remove(project);
    
public voidprojectDeleted(org.eclipse.core.resources.IProject project)

        mMap.remove(project);
    
public voidprojectOpened(org.eclipse.core.resources.IProject project)

        createProject(project);
    
public voidprojectOpenedWithWorkspace(org.eclipse.core.resources.IProject project)

        createProject(project);
    
public static voidsetup(ResourceMonitor monitor)
Sets up the resource manager with the global resource monitor.

param
monitor The global resource monitor

    
                         
         
        monitor.addProjectListener(sThis);
        int mask = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED;
        monitor.addFolderListener(sThis, mask);
        monitor.addFileListener(sThis, mask);
        
        CompiledResourcesMonitor.setupMonitor(monitor);