blob: b186ef8a31c9d388379c8489e8460f953ad1566d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2004 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
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*******************************************************************************/
package org.eclipse.wst.xml.core.internal.parser;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredTextReParser;
import org.eclipse.wst.sse.core.internal.text.StructuredDocumentReParser;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
public class XMLStructuredDocumentReParser extends StructuredDocumentReParser {
public XMLStructuredDocumentReParser() {
super();
}
protected IStructuredDocumentRegion findDirtyEnd(int end) {
// Caution: here's one place we have to cast
IStructuredDocumentRegion result = fStructuredDocument.getRegionAtCharacterOffset(end);
// if not well formed, get one past, if there is something there
if ((result != null) && (!result.isEnded())) {
if (result.getNext() != null) {
result = result.getNext();
}
}
// also, get one past if exactly equal to the end (this was needed
// as a simple fix to when a whole exact region is deleted.
// there's probably a better way.
if ((result != null) && (end == result.getEnd())) {
if (result.getNext() != null) {
result = result.getNext();
}
}
// 12/6/2001 - Since we've changed the parser/scanner to allow a lone
// '<' without
// always interpretting it as start of a tag name, we need to be a
// little fancier, in order
// to "skip" over any plain 'ol content between the lone '<' and any
// potential meating
// regions past plain 'ol content.
if (isLoneOpenFollowedByContent(result) && (result.getNext() != null)) {
result = result.getNext();
}
if (result != null)
fStructuredDocument.setCachedDocumentRegion(result);
dirtyEnd = result;
return dirtyEnd;
}
protected void findDirtyStart(int start) {
IStructuredDocumentRegion result = fStructuredDocument.getRegionAtCharacterOffset(start);
// heuristic: if the postion is exactly equal to the start, then
// go back one more, if it exists. This prevents problems with
// insertions
// of text that should be merged with the previous node instead of
// simply hung
// off of it as a separate node (ex.: XML content inserted right
// before an open
// bracket should become part of the previous content node)
if (result != null) {
IStructuredDocumentRegion previous = result.getPrevious();
if ((previous != null) && ((!(previous.isEnded())) || (start == result.getStart()))) {
result = previous;
}
// If we are now at the end of a "tag dependent" content area (or
// JSP area)
// then we need to back up all the way to the beginning of that.
IStructuredDocumentRegion potential = result;
while (isPartOfBlockRegion(potential)) {
potential = potential.getPrevious();
}
if (potential != null) {
result = potential;
fStructuredDocument.setCachedDocumentRegion(result);
}
}
dirtyStart = result;
}
/**
* The rule is, that is we are content, preceded by lone <, then we need
* to advance one more for dirty end.
*/
protected boolean isLoneOpenFollowedByContent(IStructuredDocumentRegion flatNode) {
boolean result = false;
String type = flatNode.getType();
if (type == DOMRegionContext.XML_CONTENT) {
IStructuredDocumentRegion previous = flatNode.getPrevious();
String previousType = null;
if (previous != null) {
previousType = previous.getType();
}
if (previousType != null) {
result = (previousType == DOMRegionContext.XML_TAG_OPEN);
}
}
return result;
}
protected boolean isPartOfBlockRegion(IStructuredDocumentRegion flatNode) {
boolean result = false;
String type = flatNode.getType();
result = (type == DOMRegionContext.BLOCK_TEXT);
return result;
}
public IStructuredTextReParser newInstance() {
return new XMLStructuredDocumentReParser();
}
}