/******************************************************************************* * Copyright (c) 2001, 2005 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(); } }