/******************************************************************************* * Copyright (c) 2000, 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 * Exadel, Inc. * Red Hat, Inc. *******************************************************************************/ package org.jboss.tools.jst.jsp.text.xpl; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.text.ISelectionValidator; import org.eclipse.jface.text.ISynchronizable; import org.eclipse.jface.text.ITextInputListener; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.link.LinkedModeModel; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModelExtension; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.custom.StyledText; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; import org.eclipse.wst.sse.ui.StructuredTextEditor; import org.eclipse.wst.xml.core.internal.document.NodeContainer; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText; import org.jboss.tools.common.text.xml.XmlEditorPlugin; import org.jboss.tools.common.text.xml.ui.xpl.ISelectionListenerWithSM; import org.jboss.tools.common.text.xml.ui.xpl.SelectionListenerWithSMManager; import org.jboss.tools.common.text.xml.ui.xpl.UIMessages; import org.jboss.tools.jst.jsp.preferences.xpl.PreferenceKeyGenerator; import org.jboss.tools.jst.jsp.preferences.xpl.XMLOccurrencePreferenceConstants; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Jeremy * */ public class DefaultStructuredTextOccurrenceStructureProvider implements IStructuredTextOccurrenceStructureProvider { private OccurrencesFinderJob fOccurrencesFinderJob; /** The occcurrences finder job canceler */ private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler; private ISelectionListenerWithSM fPostSelectionListenerWithSM; private IPreferenceStore fPreferenceStore; private String fEditorID; public DefaultStructuredTextOccurrenceStructureProvider(String editorID, IPreferenceStore store) { this.fEditorID = editorID; this.fPreferenceStore = store; } /** * Internal property change listener for handling changes in the editor's preferences. */ class PropertyChangeListener implements IPropertyChangeListener { /* * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { handlePreferenceStoreChanged(event); } } private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener(); /** * Holds the current occurrence annotations. * @since 3.0 */ private Annotation[] fOccurrenceAnnotations= null; /** * */ private ISelection fForcedMarkOccurrencesSelection; /** * Tells whether all occurrences of the element at the * current caret location are automatically marked in * this editor. * @since 3.0 */ private boolean fMarkOccurrenceAnnotations = true; /** * Tells whether the occurrence annotations are sticky * i.e. whether they stay even if there's no valid Java * element at the current caret position. * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>. * @since 3.0 */ private boolean fStickyOccurrenceAnnotations; /** * Tells whether to mark node occurrences in this editor. * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>. * @since 3.0 */ private boolean fMarkNodeOccurrences; /** * Tells whether to mark attribute occurrences in this editor. * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>. * @since 3.0 */ private boolean fMarkAttributeOccurrences; /** * Tells whether to mark attribute value occurrences in this editor. * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>. * @since 3.0 */ private boolean fMarkAttributeValueOccurrences; /** * Tells whether to mark attribute value occurrences in this editor. * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>. * @since 3.0 */ private boolean fMarkTextOccurrences; private String fOccurrenceProvider; /** * Finds and marks occurrence annotations. * * @since 3.0 */ protected class OccurrencesFinderJob extends Job { private IDocument fDocument; private ISelection fSelection; private ISelectionValidator fPostSelectionValidator; private boolean fCanceled= false; private IProgressMonitor fProgressMonitor; private Position[] fPositions; public OccurrencesFinderJob(IDocument document, Position[] positions, ISelection selection) { super(UIMessages.RedHatStructuredTextEditor_markOccurrences_job_name); fDocument= document; fSelection= selection; fPositions= positions; if (fEditor.getSelectionProvider() instanceof ISelectionValidator) fPostSelectionValidator= (ISelectionValidator)fEditor.getSelectionProvider(); } // cannot use cancel() because it is declared final void doCancel() { fCanceled= true; cancel(); } private boolean isCanceled() { return fCanceled || fProgressMonitor.isCanceled() || fPostSelectionValidator != null && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection) || LinkedModeModel.hasInstalledModel(fDocument); } /* * @see Job#run(org.eclipse.core.runtime.IProgressMonitor) */ public IStatus run(IProgressMonitor progressMonitor) { fProgressMonitor= progressMonitor; if (isCanceled()) return Status.CANCEL_STATUS; ITextViewer textViewer= getSourceViewer(); if (textViewer == null) return Status.CANCEL_STATUS; IDocument document= textViewer.getDocument(); if (document == null) return Status.CANCEL_STATUS; IDocumentProvider documentProvider= fEditor.getDocumentProvider(); if (documentProvider == null) return Status.CANCEL_STATUS; IAnnotationModel annotationModel= documentProvider.getAnnotationModel(fEditor.getEditorInput()); if (annotationModel == null) return Status.CANCEL_STATUS; // Add occurrence annotations int length= fPositions.length; Map annotationMap= new HashMap(length); for (int i= 0; i < length; i++) { if (isCanceled()) return Status.CANCEL_STATUS; String message; Position position= fPositions[i]; // Create & add annotation try { message= document.get(position.offset, position.length); } catch (BadLocationException ex) { XmlEditorPlugin.getPluginLog().logError(ex); // Skip this match continue; } annotationMap.put( new Annotation("org.jboss.tools.jst.jsp.occurrences", false, message), //$NON-NLS-1$ position); } if (isCanceled()) return Status.CANCEL_STATUS; synchronized (getLockObject(annotationModel)) { if (annotationModel instanceof IAnnotationModelExtension) { ((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap); } else { removeOccurrenceAnnotations(); Iterator iter= annotationMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry mapEntry= (Map.Entry)iter.next(); annotationModel.addAnnotation((Annotation)mapEntry.getKey(), (Position)mapEntry.getValue()); } } fOccurrenceAnnotations= (Annotation[])annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]); } return Status.OK_STATUS; } } /** * Returns the lock object for the given annotation model. * * @param annotationModel the annotation model * @return the annotation model's lock object * @since 3.0 */ public Object getLockObject(IAnnotationModel annotationModel) { if (annotationModel instanceof ISynchronizable) return ((ISynchronizable)annotationModel).getLockObject(); else return annotationModel; } /** * Cancels the occurrences finder job upon document changes. * * @since 3.0 */ protected class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener { public void install() { ISourceViewer sourceViewer= getSourceViewer(); if (sourceViewer == null) return; StyledText text= sourceViewer.getTextWidget(); if (text == null || text.isDisposed()) return; sourceViewer.addTextInputListener(this); IDocument document= sourceViewer.getDocument(); if (document != null) document.addDocumentListener(this); } public void uninstall() { ISourceViewer sourceViewer= getSourceViewer(); if (sourceViewer != null) sourceViewer.removeTextInputListener(this); IDocumentProvider documentProvider= fEditor.getDocumentProvider(); if (documentProvider != null) { IDocument document= documentProvider.getDocument(fEditor.getEditorInput()); if (document != null) document.removeDocumentListener(this); } } /* * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentAboutToBeChanged(DocumentEvent event) { if (fOccurrencesFinderJob != null) fOccurrencesFinderJob.doCancel(); } /* * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentChanged(DocumentEvent event) { } /* * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) */ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { if (oldInput == null) return; oldInput.removeDocumentListener(this); } /* * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) */ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { if (newInput == null) return; newInput.addDocumentListener(this); } } private StructuredTextEditor fEditor; private ProjectionViewer fViewer; /* (non-Javadoc) * @see com.ibm.sse.editor.ui.text.IStructuredTextOccurenceStructureProvider#install(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.projection.ProjectionViewer) */ public void install(StructuredTextEditor editor, ProjectionViewer viewer) { this.fEditor = editor; this.fViewer = viewer; initialize(); if (fMarkOccurrenceAnnotations) installOccurrencesFinder(); } /* (non-Javadoc) * @see com.ibm.sse.editor.ui.text.IStructuredTextOccurenceStructureProvider#uninstall() */ public void uninstall() { // cancel possible running computation fMarkOccurrenceAnnotations= false; uninstallOccurrencesFinder(); fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener); } /* (non-Javadoc) * @see com.ibm.sse.editor.ui.text.IStructuredTextOccurenceStructureProvider#initialize() */ public void initialize() { fPreferenceStore.addPropertyChangeListener(fPropertyChangeListener); fMarkOccurrenceAnnotations = fPreferenceStore.getBoolean(PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_OCCURRENCES, fEditorID)); fMarkNodeOccurrences = fPreferenceStore.getBoolean(PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_NODE_OCCURRENCES, fEditorID)); fMarkAttributeOccurrences = fPreferenceStore.getBoolean(PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_ATTRIBUTE_OCCURRENCES, fEditorID)); fMarkAttributeValueOccurrences = fPreferenceStore.getBoolean(PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_ATTRIBUTE_VALUE_OCCURRENCES, fEditorID)); fMarkTextOccurrences = fPreferenceStore.getBoolean(PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_TEXT_OCCURRENCES, fEditorID)); fStickyOccurrenceAnnotations = fPreferenceStore.getBoolean(PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_STICKY_OCCURRENCES, fEditorID)); } ProjectionViewer getSourceViewer() { return fViewer; } protected void installOccurrencesFinder() { fPostSelectionListenerWithSM= new ISelectionListenerWithSM() { public void selectionChanged(IEditorPart part, ITextSelection selection, IStructuredModel model) { updateOccurrenceAnnotations(selection, model); } }; SelectionListenerWithSMManager.getDefault().addListener(fEditor, fPostSelectionListenerWithSM); if (fEditor.getSelectionProvider() != null) { fForcedMarkOccurrencesSelection= fEditor.getSelectionProvider().getSelection(); SelectionListenerWithSMManager.getDefault().forceSelectionChange(fEditor, (ITextSelection)fForcedMarkOccurrencesSelection); } if (fOccurrencesFinderJobCanceler == null) { fOccurrencesFinderJobCanceler= new OccurrencesFinderJobCanceler(); fOccurrencesFinderJobCanceler.install(); } } protected void uninstallOccurrencesFinder() { fMarkOccurrenceAnnotations= false; if (fOccurrencesFinderJob != null) { fOccurrencesFinderJob.cancel(); fOccurrencesFinderJob= null; } if (fOccurrencesFinderJobCanceler != null) { fOccurrencesFinderJobCanceler.uninstall(); fOccurrencesFinderJobCanceler= null; } if (fPostSelectionListenerWithSM != null) { SelectionListenerWithSMManager.getDefault().removeListener(fEditor, fPostSelectionListenerWithSM); fPostSelectionListenerWithSM= null; } removeOccurrenceAnnotations(); } void removeOccurrenceAnnotations() { IDocumentProvider documentProvider= fEditor.getDocumentProvider(); if (documentProvider == null) return; IAnnotationModel annotationModel= documentProvider.getAnnotationModel(fEditor.getEditorInput()); if (annotationModel == null || fOccurrenceAnnotations == null) return; synchronized (getLockObject(annotationModel)) { if (annotationModel instanceof IAnnotationModelExtension) { ((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, null); } else { for (int i= 0, length= fOccurrenceAnnotations.length; i < length; i++) annotationModel.removeAnnotation(fOccurrenceAnnotations[i]); } fOccurrenceAnnotations= null; } } /** * Updates the occurrences annotations based * on the current selection. * * @param selection the text selection * @param astRoot the compilation unit AST * @since 3.0 */ protected void updateOccurrenceAnnotations(ITextSelection selection, IStructuredModel model) { if (fOccurrencesFinderJob != null) fOccurrencesFinderJob.cancel(); if (!fMarkOccurrenceAnnotations) return; if (model == null || selection == null) return; IDocument document= getSourceViewer().getDocument(); if (document == null) return; String message; Document dom = (model instanceof IDOMModel) ? ((IDOMModel) model).getDocument() : null; List matches = findMatches(dom, model, selection); if (matches == null || matches.size() == 0) { if (!fStickyOccurrenceAnnotations) removeOccurrenceAnnotations(); return; } List positionsList = new ArrayList(); int i= 0; for (Iterator each= matches.iterator(); each.hasNext();) { Object current = each.next(); if (current instanceof IDOMElement) { IDOMElement currentNode = (IDOMElement)current; // Add start tag int start = currentNode.getStartOffset(); int end = currentNode.getStartEndOffset(); positionsList.add(new Position(start, end - start)); if (currentNode.hasEndTag()) { //Add end tag start = currentNode.getEndStartOffset(); end = currentNode.getEndOffset(); positionsList.add(new Position(start, end - start)); } } else if (current instanceof ITextRegion) { ITextRegion currentRegion = (ITextRegion)current; positionsList.add(new Position(currentRegion.getStart(), currentRegion.getLength())); } else if (current instanceof Position) { Position currentPosition = (Position)current; positionsList.add(new Position(currentPosition.getOffset(), currentPosition.getLength())); } } if (positionsList.size() == 0) return; fOccurrencesFinderJob= new OccurrencesFinderJob(document, (Position[])positionsList.toArray(new Position[positionsList.size()]), selection); fOccurrencesFinderJob.run(new NullProgressMonitor()); } private List findMatches(Document dom, IStructuredModel model, ITextSelection selection) { try { IndexedRegion region = ((IDOMModel)model).getIndexedRegion(selection.getOffset()); if (region instanceof IDOMElement) { IDOMElement xmlElement = (IDOMElement)region; NamedNodeMap attrs = xmlElement.getAttributes(); for (int i = 0; attrs != null && i < attrs.getLength(); i++) { IDOMAttr xmlAttr = (IDOMAttr)attrs.item(i); if (xmlAttr.contains(selection.getOffset())) { if (selection.getOffset() >= xmlAttr.getNameRegionStartOffset() && selection.getOffset() <= xmlAttr.getNameRegionEndOffset()) { return findTagAttrNameMatches(dom, xmlElement.getTagName(), xmlAttr.getName()); } else if (selection.getOffset() >= xmlAttr.getValueRegionStartOffset() && selection.getOffset() <= xmlAttr.getEndOffset()) { return findTagAttrValueMatches(dom, xmlAttr.getValue()); } } } return findTagMatches(dom, xmlElement.getTagName()); } else if (region instanceof IDOMText) { IDOMText xmlText = (IDOMText)region; return findTextMatches(dom, xmlText.getData().trim()); } } catch (DOMException x) { XmlEditorPlugin.getPluginLog().logError(x); } return new ArrayList(); } private List findTagMatches(Document dom, String tagName) { List matches = new ArrayList(); if (fMarkNodeOccurrences) { NodeList children = (NodeContainer)dom.getChildNodes(); for (int i = 0; children != null && i < children.getLength(); i++) { if(children.item(i) instanceof IDOMNode) { IDOMNode xmlNode = (IDOMNode)children.item(i); addTagOccurencies(matches, xmlNode, tagName); } } } return matches; } private void addTagOccurencies(List matches, IDOMNode xmlNode, String tagName) { if (matches == null || xmlNode == null || tagName == null) return; if (xmlNode instanceof IDOMElement) { IDOMElement xmlElement = (IDOMElement)xmlNode; if (tagName.equals(xmlElement.getTagName())) matches.add(xmlElement); } for (Node child = xmlNode.getFirstChild(); child != null; child = child.getNextSibling()) { if (child instanceof IDOMNode) { addTagOccurencies(matches, (IDOMNode)child, tagName); } } } private List findTagAttrNameMatches(Document dom, String tagName, String attrName) { List matches = new ArrayList(); if (fMarkAttributeOccurrences) { NodeList children = (NodeContainer)dom.getChildNodes(); for (int i = 0; children != null && i < children.getLength(); i++) { if(children.item(i) instanceof IDOMNode) { IDOMNode xmlNode = (IDOMNode)children.item(i); addTagAttrNameOccurencies(matches, xmlNode, attrName); } } } return matches; } private void addTagAttrNameOccurencies(List matches, IDOMNode xmlNode, String attrName) { if (matches == null || xmlNode == null || attrName == null) return; if (xmlNode instanceof IDOMElement) { IDOMElement xmlElement = (IDOMElement)xmlNode; NamedNodeMap attrs = xmlElement.getAttributes(); for (int i = 0; attrs != null && i < attrs.getLength(); i++) { IDOMAttr xmlAttr = (IDOMAttr)attrs.item(i); if (attrName.equals(xmlAttr.getName())) { matches.add(new Position(xmlAttr.getNameRegionStartOffset(), xmlAttr.getNameRegionTextEndOffset() - xmlAttr.getNameRegionStartOffset())); } } } for (Node child = xmlNode.getFirstChild(); child != null; child = child.getNextSibling()) { if (child instanceof IDOMNode) { addTagAttrNameOccurencies(matches, (IDOMNode)child, attrName); } } } private List findTagAttrValueMatches(Document dom, String attrValue) { List matches = new ArrayList(); if (fMarkAttributeValueOccurrences) { NodeList children = (NodeContainer)dom.getChildNodes(); for (int i = 0; children != null && i < children.getLength(); i++) { if(children.item(i) instanceof IDOMNode) { IDOMNode xmlNode = (IDOMNode)children.item(i); addTagAttrValueOccurencies(matches, xmlNode, attrValue); } } } return matches; } private void addTagAttrValueOccurencies(List matches, IDOMNode xmlNode, String attrValue ) { if (matches == null || xmlNode == null || attrValue == null) return; if (xmlNode instanceof IDOMElement) { IDOMElement xmlElement = (IDOMElement)xmlNode; NamedNodeMap attrs = xmlElement.getAttributes(); for (int i = 0; attrs != null && i < attrs.getLength(); i++) { IDOMAttr xmlAttr = (IDOMAttr)attrs.item(i); String value = xmlAttr.getValueRegionText(); if (attrValue.equals(xmlAttr.getValue())) matches.add(new Position(xmlAttr.getValueRegionStartOffset(), value == null ? 0 : value.length())); } } for (Node child = xmlNode.getFirstChild(); child != null; child = child.getNextSibling()) { if (child instanceof IDOMNode) { addTagAttrValueOccurencies(matches, (IDOMNode)child, attrValue); } } } private List findTextMatches(Document dom, String data) { List matches = new ArrayList(); if (fMarkTextOccurrences && !isEmptyString (data)) { NodeList children = (NodeContainer)dom.getChildNodes(); for (int i = 0; children != null && i < children.getLength(); i++) { if (children.item(i) instanceof IDOMNode) { IDOMNode xmlNode = (IDOMNode)children.item(i); addTextOccurencies(matches, xmlNode, data); } } } return matches; } private boolean isEmptyString(String str) { return str == null || str.trim().length() == 0; } private void addTextOccurencies(List matches, IDOMNode xmlNode, String data) { if (matches == null || xmlNode == null || data == null) return; if (xmlNode instanceof IDOMText) { IDOMText xmlText = (IDOMText)xmlNode; String xmlData = xmlText.getData(); if (xmlData != null && xmlData.indexOf(data) != -1) { matches.add( new Position( xmlText.getStartOffset() + xmlData.indexOf(data), data.length())); } } for (Node child = xmlNode.getFirstChild(); child != null; child = child.getNextSibling()) { if (child instanceof IDOMNode) { addTextOccurencies(matches, (IDOMNode)child, data); } } } private boolean getEventNewBooleanValue(PropertyChangeEvent event) { return Boolean.getBoolean(event.getNewValue().toString()); } /* * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent) */ public void handlePreferenceStoreChanged(PropertyChangeEvent event) { ISourceViewer sourceViewer= getSourceViewer(); if (getSourceViewer() != null) { String property= event.getProperty(); if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_OCCURRENCES, fEditorID).equals(property)) { boolean markOccurrences = getEventNewBooleanValue(event); if (markOccurrences != fMarkOccurrenceAnnotations) { fMarkOccurrenceAnnotations= markOccurrences; if (!fMarkOccurrenceAnnotations) { uninstallOccurrencesFinder(); } else { installOccurrencesFinder(); } } } else if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_OCCURRENCE_PROVIDER, fEditorID).equals(property)) { if (event.getNewValue() instanceof String) { String occurrenceProvider= (String)event.getNewValue(); if (occurrenceProvider != fOccurrenceProvider) { fOccurrenceProvider= occurrenceProvider; if (fMarkOccurrenceAnnotations) { uninstallOccurrencesFinder(); installOccurrencesFinder(); } } } } else if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_NODE_OCCURRENCES, fEditorID).equals(property)) { fMarkNodeOccurrences= getEventNewBooleanValue(event); } else if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_ATTRIBUTE_OCCURRENCES, fEditorID).equals(property)) { fMarkAttributeOccurrences= getEventNewBooleanValue(event); } else if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_ATTRIBUTE_VALUE_OCCURRENCES, fEditorID).equals(property)) { fMarkAttributeValueOccurrences= getEventNewBooleanValue(event); } else if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_MARK_TEXT_OCCURRENCES, fEditorID).equals(property)) { fMarkAttributeValueOccurrences= getEventNewBooleanValue(event); } else if (PreferenceKeyGenerator.generateKey( XMLOccurrencePreferenceConstants.EDITOR_STICKY_OCCURRENCES, fEditorID).equals(property)) { fStickyOccurrenceAnnotations= getEventNewBooleanValue(event); } } } /* (non-Javadoc) * @see com.ibm.sse.editor.ui.text.IStructuredTextOccurenceStructureProvider#affectsPreferences(java.lang.String) */ public boolean affectsPreferences(String property) { return XMLOccurrencePreferenceConstants.affectsPreferences(property); } public IPreferenceStore getPreferenceStore() { return fPreferenceStore; } public String getEditorId() { return fEditorID; } }