/*******************************************************************************
* 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;
}
}