| /* |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| package org.apache.batik.util.gui.xmleditor; |
| |
| import javax.swing.text.AttributeSet; |
| import javax.swing.text.BadLocationException; |
| import javax.swing.text.Element; |
| import javax.swing.text.PlainDocument; |
| |
| /** |
| * A document that can be marked up using XML style. |
| * |
| * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a> |
| * @version $Id$ |
| */ |
| public class XMLDocument extends PlainDocument { |
| |
| protected XMLScanner lexer; |
| protected XMLContext context; |
| |
| protected XMLToken cacheToken = null; |
| |
| public XMLDocument() { |
| this(new XMLContext()); |
| } |
| |
| /** Creates a new instance of XMLDocument |
| * @param context XMLContext |
| */ |
| public XMLDocument(XMLContext context) { |
| //super(context); |
| this.context = context; |
| lexer = new XMLScanner(); |
| } |
| |
| /** Return XMLToken |
| * @param pos position |
| * @return XMLToken |
| */ |
| public XMLToken getScannerStart(int pos) throws BadLocationException { |
| int ctx = XMLScanner.CHARACTER_DATA_CONTEXT; |
| int offset = 0; |
| int tokenOffset = 0; |
| |
| if (cacheToken != null) { |
| if (cacheToken.getStartOffset() > pos) { |
| cacheToken = null; |
| } else { |
| ctx = cacheToken.getContext(); |
| offset = cacheToken.getStartOffset(); |
| tokenOffset = offset; |
| |
| Element element = getDefaultRootElement(); |
| int line1 = element.getElementIndex(pos); |
| int line2 = element.getElementIndex(offset); |
| |
| //if (pos - offset <= 1800 ) { |
| if (line1 - line2 < 50) { |
| return cacheToken; |
| } |
| } |
| } |
| |
| String str = getText(offset, pos - offset); |
| lexer.setString(str); |
| lexer.reset(); |
| |
| // read until pos |
| int lastCtx = ctx; |
| int lastOffset = offset; |
| while (offset < pos) { |
| lastOffset = offset; |
| lastCtx = ctx; |
| |
| offset = lexer.scan(ctx) + tokenOffset; |
| ctx = lexer.getScanValue(); |
| } |
| cacheToken = new XMLToken(lastCtx, lastOffset, offset); |
| return cacheToken; |
| } |
| |
| /** {@inheritDoc} */ |
| public void insertString(int offset, String str, AttributeSet a) |
| throws BadLocationException { |
| |
| super.insertString(offset, str, a); |
| |
| if (cacheToken != null) { |
| if (cacheToken.getStartOffset() >= offset) { |
| cacheToken = null; |
| } |
| } |
| |
| } |
| |
| /** {@inheritDoc} */ |
| public void remove(int offs, int len) throws BadLocationException { |
| super.remove(offs, len); |
| |
| if (cacheToken != null) { |
| if (cacheToken.getStartOffset() >= offs) { |
| cacheToken = null; |
| } |
| } |
| } |
| |
| /** |
| * Find the first occurrence of the specified String starting at the specified index. |
| * @param str String to find |
| * @param fromIndex |
| * @param caseSensitive true or false |
| * @return the offset if the string argument occurs as a substring, otherwise return -1 |
| * @throws BadLocationException if fromIndex was not a valid part of the document |
| */ |
| public int find(String str, int fromIndex, boolean caseSensitive) |
| throws BadLocationException { |
| |
| int offset = -1; |
| int startOffset = -1; |
| int len = 0; |
| int charIndex = 0; |
| |
| Element rootElement = getDefaultRootElement(); |
| |
| int elementIndex = rootElement.getElementIndex(fromIndex); |
| if (elementIndex < 0) { return offset; } |
| |
| // set the initial charIndex |
| charIndex = fromIndex - |
| rootElement.getElement(elementIndex).getStartOffset(); |
| |
| for (int i = elementIndex; i < rootElement.getElementCount(); i++) { |
| Element element = rootElement.getElement(i); |
| startOffset = element.getStartOffset(); |
| if (element.getEndOffset() > getLength()) { |
| len = getLength() - startOffset; |
| } else { |
| len = element.getEndOffset() - startOffset; |
| } |
| |
| String text = getText(startOffset, len); |
| |
| if (!caseSensitive) { |
| text = text.toLowerCase(); |
| str = str.toLowerCase(); |
| } |
| |
| charIndex = text.indexOf(str, charIndex); |
| if (charIndex != -1) { |
| offset = startOffset + charIndex; |
| break; |
| } |
| charIndex = 0; // reset the charIndex |
| } |
| |
| return offset; |
| } |
| } |