630 likes | 827 Views
Eclipse resource management. Outline. Introduction Basic resource management Further resource management. Introduction. Package org.eclipse.core.resources Define the notions of workspaces and resources Provides basic support for managing a workspace and its resources for resource plug-in
E N D
Outline • Introduction • Basic resource management • Further resource management
Introduction • Package org.eclipse.core.resources • Define the notions of workspaces and resources • Provides basic support for managing a workspace and its resources for resource plug-in • Resource retrieve, create, delete, move ..Etc. • Tracking resource lifecycle changes • Similar to a file system
Basic resource management • Resource and the workspace • Resource and the local file system • Resource properties
Resource and the workspace • Workspace : central hub of user’s file • Plug-in use resource API to create, navigate, manipulate resource in the workspace • Three kinds of resource • Project • Folder • file
Resources (I) • Project • Collection of folders and files • Organize resources related to specific projects • Interface IProject • Folder • Contains other folder and files • Like directory in file system • Interface IFolder
Resource (II) • File • Arbitrary sequence of bytes • Interface IFile • Interface Iworkspace • Interface IResource
Tree structure Project at top Folder and file underneath Workspace root Resource organization
Resource and file system • When resource plug-in is activate, the workspace is represented by an instance of IWorkspace • The IWorkspace instance represent all files and directories in file system • Get the IWorkspace instance : ResourcePlugin.getWorkspace();
Manipulate resource • First get the IWorkspaceRoot instance, which represents the root of the resource tree in the workspace • Access projects in the workspace • Access folders and files in projects • Access files in folders • Similar to java.io.File
Get and open project IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IProject myWebProject = myWorkspaceRoot.getProject("MyWeb"); // open if necessary if (myWebProject.exists() && !myWebProject.isOpen()) myWebProject.open(null);
Get folder, create file IFolder imagesFolder = myWebProject.getFolder("images"); if (imagesFolder.exists()) { // create a new file IFile newLogo = imagesFolder.getFile("newLogo.gif"); FileInputStream fileStream = new FileInputStream( "c:/MyOtherData/newLogo.gif"); newLogo.create(fileStream, false, null); // create closes the file stream, so no worries. }
File copy IFile logo = imagesFolder.getFile("logo.gif"); if (logo.exists()) { IPath newLogoPath = new Path("newLogo.gif"); logo.copy(newLogoPath, false, null); IFile newLogo = imagesFolder.getFile("newLogo.gif"); ... }
File move IFolder newImagesFolder = myWebProject.getFolder("newimages"); newImagesFolder.create(false, true, null); IPath renamedPath = newImagesFolder.getFullPath() .append("renamedLogo.gif"); newLogo.move(renamedPath, false, null); IFile renamedLogo = newImagesFolder.getFile("renamedLogo.gif");
Resource and real file location • Use IResource.getLocation() to get the full system path of a resource • Use IProjectDescription.setLocation() to change a project location • Get a resource via a file system path IWorkspaceRoot.getFileForLocation() IWorkspaceRoot.getContainerForLocation()
Resource properties • Session properties • Cache information in key-value pair in memory • Lost when a resource is deleted or the project or workspace is closed • Persistent properties • Store resource-specific information on disk • Store with system metadata and maintained across platform shutdown and restart
Used Interface and class • Class ResourcePlugin • The plug-in run-time class • The start point for resource manipulation • Interface IWorkspace • Represent the workspace in the platform • Interface IResource • The resource in the workspace • Superinterface of IFile, IFolder, IProject, IWorkspaceRoot
Used interface and class • Interface IFile, IFolder, IProject, IWorkspaceRoot • System resource instance • Provide manipulation methods of resources • Interface IProjectDescription • Contain the metadata require to define a project • Contain the information in file .project with all projects
Further resource management • Resource markers • Tracking resource changes • Incremental project builders • Workspace save participation • Project natures • Derived resource • Resource modification hooks
Marker • a general mechanism for associating notes and meta-data with resources. • Like a small tag to a resource • Record information about a problem or a task, or simply record a location as bookmark • User can jump to the marked location within a resource • Platform defined five standard markers (marker, taskmarker, problemmark,bookmark,textmark)
Properties of a marker • type : String • id : long // unique in its resource • + additional attributes depending on specific type of the parker.
Predefined Marker types • org.eclipse.core.resource.marker (IMarker.MARKER) • o.e.c.r.taskmarker (IMarker.TASK) • o.e.c.r.problemmarker (IMarker.PROBLEM) • o.e.c.r.bookmark (IMarker.BOOKMARK) • o.e.c.r.textmarker(IMarker.TEXT) • additional markers can be defined by using the extention point: • o.e.c.r.markers
Marker type declaration • id=“type” • is the unique name (type) of the marker type • <super type=“superType” />* • super types of this marker types. • <attribute name=“attName” />* • attributes which may be present on this type of markers • <persistent value=“false”/>? • whether markers of this type should be persisted by the platform • Instances can be transient if TRANSIENT attr is set to true.
<extension id="problemmarker“ point="org.eclipse.core.resources.markers“ name="%problemName"> <super type="org.eclipse.core.resources.marker"/> <persistent value="true"/> <attribute name="severity"/> <attribute name="message"/> <attribute name="location"/> </extension> <extension id="taskmarker" point="org.eclipse.core.resources.markers“ name="%taskName"> <super type="org.eclipse.core.resources.marker"/> <persistent value="true"/> <attribute name="priority"/> <attribute name="message"/> <attribute name="done"/> <attribute name="userEditable"/> </extension>
IMarker.BOOKMARK <extension id="bookmark" point="org.eclipse.core.resources.markers" name="%bookmarkName“> <super type="org.eclipse.core.resources.marker"/> <persistent value="true"/> <attribute name="message"/> <attribute name="location"/> </extension> <extension id=“marker” point = .. name= ..> <persistent type = “true”/> <attribute name=“transient”/> </extension>
the text marker • TextMarker (IMarker.TEXT) • IMarker.CHAR_START : int // (0-based) • IMarker.CHAR_END : int // exclusive • IMarker.LINE_NUMBER:int // 1-based • IMARK.TRANSIENT: boolen // inherited • used with other markers in editor framework.
the Bookmark and taskmarker • IMareker.BOOKMARK • IMarker.MESSAGE :String • IMarker.LOCATION:String • IMarker.TASK • IMarker.PRIORITY: int • IMarker.PRIORITY_HIGH, _NORMAL, _LOW • IMarker.MESSAGE • IMarker.DONE :boolean // completed
Problem Marker (o.e.c.rproblemmarker) • IMarker.PROBLEM • IMarker.SEVERITY :int • IMarker.SEVERITY_ERROR, _WARNING, _INFO • (2) (1) (0) • IMarker.MESSAGE:String • IMarker.LOCATION :String
Resource API defines methods for creating, setting value, extending the platform with new marker type • Platform manage markers, it will throw away markers attached to resource that are deleted • Plug-in control marker’s creation, removal and attribute value. It also removes markers that no longer apply to a resource • Interface IMarker
Marker operationIResource.createMarker(type) • Marker creation • Using factory method IResource.createMarker() • Ex: IMarker marker = file.createMarker(IMarker.TASK); • // file is now the resource of marker. • Marker deletion • Ex: try { marker.delete(); } catch (CoreException e) { // Something went wrong }
Marker attributes access • <T> getAttribute(String name, T defValue ) • possible <T>: boolean, int, String. • setAttribute(String name, <T> value) • possible <T> : String, int, boolean,
Batch delete int depth = IResource.DEPTH_INFINITE; // others: _ZERO, _ONE try { resource.deleteMarkers(IMarker.PROBLEM, true/*subType*/, depth); } catch (CoreException e) { // something went wrong } • Attribute setting if (marker.exists()) { try { marker.setAttribute(IMarker.MESSAGE, "A sample marker message"); marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); } catch (CoreException e) { // You need to handle the case where the marker no longer exists } }
Querying markers • Resource can be queried for their markers and the markers of their children IMarker[] problems = null; int depth = IResource.DEPTH_INFINITE; boolean subtype = true ; try { problems = resource.findMarkers(IMarker.PROBLEM, subtype, depth); } catch (CoreException e) { // something went wrong }
Extend the platform with new marker type • New marker type are derived from existing ones using multiple inheritance, • it will inherit all of the attribute from supertypes • Plug-ins must declare new marker type in plugin.xml before using it • Persistent Markers saved when workspace is saved.
Marker extension <extension id="mymarker" <-- marker type --> point="org.eclipse.core.resources.markers" /> <extension id="myproblem" point="org.eclipse.core.resources.markers"> <super type="org.eclipse.core.resources.problemmarker"/> <super type="com.example.markers.mymarker"/> <attribute name="myAttribute" /> <persistent value="true" /> </extension>
public IMarker createMyMarker(IResource resource){ try { Imarker marker= resource.createMarker("com.example.markers.myproblem"); // marker id marker.setAttribute("myAttribute", "MYVALUE"); return marker; } catch (CoreException e) { // You need to handle the cases where attribute value is rejected } }
Tracking resource changes • The resource API include a event mechanism for resource changes • Use IResourceChangeListener and IResourceChangeEvent to track resource change • Method that create, delete or change a resource typically trigger a resource change event
Must register a resource change listener with the workspace IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace().addResourceChangeListener( listener, IResourceChangeEvent.POST_CHANGE); • Use IWorkspace.run(runnable,monitor) can batch the change operation, resource change event will be triggered once when the runnable is completed
Resource deltas • Resource change event contains a resource delta that describes the net effect of change • Structured as a tree rooted at the workspace root • Describe four type of resource change • Created, deleted, or changed • Moved or renamed via IResource.move() • Marker that has been added, removed, or changed • Files that has been modified
To traverse a resource tree, implement the interface IResourceDeltaVisitor or using IResourceDelta.getAffectedChildren()
Resource change event • PRE_CLOSE • PRE_DELETE • PRE_AUTOBUILD • POST_AUTOBUILE • POST_CHANGE
Implementing a resource change listener IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace() .addResourceChangeListener(listener, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.PRE_AUTO_BUILD| IResourceChangeEvent.POST_AUTO_BUILD | IResourceChangeEvent.POST_CHANGE);
public class MyResourceChangeReporter implements IResourceChangeListener { public void resourceChanged(IResourceChangeEvent event) { IResource res = event.getResource(); switch (event.getType()) { case IResourceChangeEvent.PRE_CLOSE: System.out.print("Project "); System.out.print(res.getFullPath()); System.out.println(" is about to close."); break; case IResourceChangeEvent.PRE_DELETE: System.out.print("Project "); System.out.print(res.getFullPath()); System.out.println(" is about to be deleted."); break; case IResourceChangeEvent.POST_CHANGE: System.out.println("Resources have changed."); event.getDelta().accept(new DeltaPrinter()); break; } } }
Incremental project builder • Manipulate the resource in a project in a fashion defined by the builder itself • Often used to apply a transformation on a resource to produce a resource or other kind • Platform define two kind of builds • Full build • Incremental build
Incremental builds are seeded with a resource change delta to reflect the net effect of all resource change
Invoke a build • A build can be invoked in two ways • IProject.build() for the reciving project • IWorkspace.build() for all open project in the workspace • An incremental project builders are also invoked implicitly by the platform during an auto-build
Defining an incremental project builder <extension id="mybuilder" name="My Sample Builder" point="org.eclipse.core.resources.builders"> <builder <run class="com.example.builders.BuilderExample"> <parameter name="optimize" value="true" /> <parameter name="comment" value="Builder comment" /> </run> </builder> </extension>
public class BuilderExample extends IncrementalProjectBuilder{ IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { // add your build logic here return null; } Protected void startupOnInitialize() { // add builder init logic here } }
Builder implementation protected IProject[] build(int kind, Map args, IProgressMonitor monitor throws CoreException { if (kind == IncrementalProjectBuilder.FULL_BUILD) { fullBuild(monitor); } //full build else { IResourceDelta delta = getDelta(getProject()); if (delta == null) { fullBuild(monitor); } // auto build else { incrementalBuild(delta, monitor); } } return null; }
protected void fullBuild(final IProgressMonitor monitor) throws CoreException { try { getProject().accept(new MyBuildVisitor()); } catch (CoreException e) { } } class MyBuildVisitor implements IResourceVisitor { public boolean visit(IResource res) { //build the specified resource. //return true to continue visiting children. return true; } }