Marker

Aus Eclipse
Wechseln zu: Navigation, Suche

Marker werden dazu verwendet in den Quell-Ressourcen bestimmten Stellen zu markieren und mit entsprechenden Hinweisen für den Benutzer zu versehen. Ein Marker tritt somit im Editor einer Ressource visuell in Erscheinung und erleichtert so z.B. dem Benutzer die Zuordnung eines Problems zu einer Codestelle wesentlich. Dabei verändert das Einfügen eines Marker die ausgezeichneten Quell-Ressourcen nicht, die Informationen werden im Workspace abgelegt und nicht etwa in der Ressource selbst. Der Editor hat letztendlich die Aufgabe die Daten der Ressource und die darauf definierten Marker gemeinsam darzustellen. Auch hier beschränkt sich die Anwendung nicht nur auf Quellcode-Dateien, alle Quell-Ressourcen die vom Builder übersetzt werden, können auch mit Markern versehen werden (so es denn einen Editor dafür gibt). Typische Fälle für den Einsatz von Markern sind die Markierung von Compiler-Fehlern oder Warnings einer Code-Datei, aber auch Bookmarks und Task (z.B. TODO).

Deklaration

Marker sind ebenfalls im Plug-In-Manifest zu deklarieren damit sie vom Eclipse-Framework angewendet werden könnnen. Die Deklaration eines Markers besteht wiederum aus einer Id, einem Namen und der Angabe des Extension-Points "org.eclipse.core.resources.markers".Die Deklaration eines Markers enthält jedoch keinen Verweise auf Plugin-spezifische Implementierung in Form eines Java-Classfiles. Stattdessen gibt die Deklaration eines Markers einen oder mehrere Supertypen an von denen der neu deklarierte Marker "ableitet". Wobei es sich hier nicht um eine Ableitung im objektorientierten Sinne handelt, denn über diese Art der Deklaration kann natürlich kein neues Verhalten definiert werden. Ein Plug-In-spezifischer Marker kann aber zusätzliche Attribute definieren , die eben von den Supertypen nicht bereitgestellt werden.

plugin.xml Deklaration eines Markers

     <extension
          id="myProblem"
          name="My Problem"
          point="org.eclipse.core.resources.markers">
       <super
          type="org.eclipse.core.resources.problemmarker">
       </super>
       <attribute name = "key">
       <attribute name = "rule">
       <persistent
          value="true">
       </persistent>
    </extension>

Die Angabe des/der Supertypen steuert in welchen Views ein Marker angezeigt wird. Dabei werden Marker mit dem supertyp org.eclipse.core.resources.problemmarker in der Problemview org.eclipse.core.resources.taskmarker in der TaskView, sowie org.eclipse.core.resources.bookmark in der Bookmark-View angezeigt. Das Element persistent steuert ob ein Marker über eine Eclipse-Session hinweg gespeichert wird. Die Deklaration der Attribute [Zitat: Ruble/Clayberg] ist optional, das Eclipse-Framework macht derzeit keinerlei Prüfung ob z.b. ein Builder beim Erstellen eines Markers nur genau die deklarierten Attribute verwendet. Die Deklaration der Attribute eines Markers hat somit eigentlich reinen Dokumentationscharakter.

Supertypen und Views

Marker Views1.png

Erstellen eines Markers

Wie bereits gesagt ist die gesamte Funktionalität des Markers in den Supertypen implementiert, womit dem Anwender nur noch die Aufgabe zufällt den Marker bei der Erstellung mit den Detail-Informationen für den konkreten Anwendungsfall zu versehen. Die Detailinformationen eines Markers werden dabei über die Attribute zugewiesen, diese sind in Form einer Liste von Schlüssel/Werte-Paaren anzugeben. Der Schlüssel ist dabei entweder ein Attributname des Basistypen oder eben ein selbst definiertes Attribut. Wichtig ist dabei daß für die Attribute der Supertypen in den Views bereits entsprechende Stellen vorgesehen sind an denen diese Atribute angezeigt werden. Beispiel dafür sind Meldungsstext,Zeilennummer in der Datei,Schweregrad.

Folgende Methode zeigt an einem Beispiel die Erstellung eines Markers

  private static final String MARKER_TYPE = "besi.mybuilder.plugin.myProblem";
  private void addMarker(IFile file, String message, int lineNumber,int severity) {
 
       try {
             IMarker marker = file.createMarker(MARKER_TYPE);
             marker.setAttribute(IMarker.MESSAGE, message);
             marker.setAttribute(IMarker.SEVERITY, severity);
             if (lineNumber == -1) {
                lineNumber = 1;
             }
             marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
        }
        catch (CoreException e) {}
  }

Die in den Supertypen vordefinerten Attribute sind Text-Konstanten und befinden sich im Interface IMarker und können wie in diesem Codebeispiel gezeigt eingesetzt werden. Häufig verwendete Attribute sind:

  • LINE_NUMBER - Gibt die Zeilennummer in einer Ressource an ,dieses Attribute wird verwendet um dem Marker in einem Editor an der richtigen Stelle einzublenden
  • SEVERITY - Gibt den Schweregrad eines Fehlers an, damit werden die Icons gesteuert
  • MESSAGE - Gibt eine Beschreibung für den Marker an, die dem Benutzer angezeigt wird
  • LOCATION - Gibt die Position in eine Resource in Menschen-lesbarer Form an

Löschen eines Markers

Um einen Marker zu löschen gibt es mehrere Möglichkeiten.Falls man eine Referenz auf ein Marker-Objekt zur Verfügung hat kann man über das Interface IMarker die Methode delete aufrufen. Eine Referenz auf einen exisitierenden Marker erhält man beispielsweise beim Aufruf eines QuickFixes in dessen Methode run und kann somit den Marker nach Abschluss des QuickFixes löschen. Einen anderen Weg eine Referenz auf ein Marker-Objekt zu bekommen ist es über die Marker eines Projekts zu iterieren , dazu stellt IProject die Methode findMarkers zur Verfügung. Diese Methode erlaubt es selektiv nur bestimmte Marker zu suchen. Eine andere Möglichkeit Maker zu löschen ist die Methode deleteMarkers von IProject:

   private void DeleteMarker1(IProject myProject,String markerType){		
 
       IMarker[] markers = null;
       try{
	    markers = myProject.findMarkers( null, true, IResource.DEPTH_INFINITE );
	    for (IMarker marker: markers) 
	    { 
               if(marker.getType() == markerType)	
	       marker.delete();
            }	
        }catch(CoreException e){}	
   }
 
   private void deleteMarkers(IProject myProject,String markerType){
 
	try {
	     myProject.deleteMarkers(markerType , false, IResource.DEPTH_INFINITE);
 
	} catch (CoreException e) {}
    }

Synchronisation von Ressource und Marker

Die Synchronisation der Marker mit den Ressourcen hängt von der Implementierung der Plugin's ab. Allen gemeinsam ist dass ein Marker vom Eclipse-Framework über den Editor quasi in die Ressource "hineinprojeziert" wird, also selbst nicht Teil der Ressource ist. Üblicherweise wird das Erstellen eines Markers vom jeweiligen Builder vorgenommen, die Anzeige der Marker vom Editor, das Löschen der Markers wird vom Builder nach dem Build und vor dem Erstellen der Marker vorgenommen, weiters werden einzelne Marker durch QuickFixes gelöscht. Eine konkrete Implementierung eines Plugin's könnte jedoch auch anders verfahren, da die genauen Zeitpunkte für das Erstellen und Löschen eines Markers vom Eclipse-Framework nicht vorgegeben werden. Wenn ein Marker persistent gespeichert wird, dann erfolgt dies konsequenterweise über die Projekt-Datei .project und nicht etwa über die Ressource selber.

Siehe auch