2 * Copyright (c) 2002-2004 Widespace, OU and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * Igor Malinin - initial contribution
11 * $Id: PHPXMLPartitionScanner.java,v 1.1 2005-05-15 23:23:02 axelcl Exp $
14 package net.sourceforge.phpeclipse.xml.ui.internal.text;
16 import java.util.HashMap;
19 import org.eclipse.jface.text.Assert;
20 import org.eclipse.jface.text.BadLocationException;
21 import org.eclipse.jface.text.IDocument;
22 import org.eclipse.jface.text.rules.ICharacterScanner;
23 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
24 import org.eclipse.jface.text.rules.IToken;
25 import org.eclipse.jface.text.rules.Token;
31 * @author Igor Malinin
33 public class PHPXMLPartitionScanner implements IPartitionTokenScanner {
34 // public static final String XML_PI = "__xml_processing_instruction";
35 public static final String XML_COMMENT = "__xml_comment";
36 public static final String XML_DECL = "__xml_declaration";
37 public static final String XML_TAG = "__xml_tag";
38 public static final String XML_ATTRIBUTE = "__xml_attribute";
39 public static final String XML_CDATA = "__xml_cdata";
41 public static final String DTD_INTERNAL = "__dtd_internal";
42 // public static final String DTD_INTERNAL_PI = "__dtd_internal_pi";
43 public static final String DTD_INTERNAL_COMMENT = "__dtd_internal_comment";
44 public static final String DTD_INTERNAL_DECL = "__dtd_internal_declaration";
45 public static final String DTD_CONDITIONAL = "__dtd_conditional";
47 public static final int STATE_DEFAULT = 0;
48 public static final int STATE_TAG = 1;
49 public static final int STATE_DECL = 2;
50 public static final int STATE_CDATA = 4;
52 public static final int STATE_INTERNAL = 8;
54 protected IDocument document;
60 protected int position;
63 protected boolean parsedtd;
65 protected Map tokens = new HashMap();
67 public PHPXMLPartitionScanner(boolean parsedtd) {
68 this.parsedtd = parsedtd;
72 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
74 public IToken nextToken() {
79 return nextTagToken();
82 return nextDeclToken();
85 return nextCDATAToken();
89 case ICharacterScanner.EOF:
90 state = STATE_DEFAULT;
91 return getToken(null);
95 case ICharacterScanner.EOF:
96 if (parsedtd || isInternal()) {
100 state = STATE_DEFAULT;
101 return getToken(XML_TAG);
106 // return nextPIToken();
108 case '!': // <! <!DEFINITION or <![CDATA[ or <!--COMMENT
110 case ICharacterScanner.EOF:
111 state = STATE_DEFAULT;
112 return getToken(XML_TAG);
114 case '-': // <!- <!--COMMENT
116 case ICharacterScanner.EOF:
117 return nextDeclToken();
120 return nextCommentToken();
123 case '[': // <![ <![CDATA[ or <![%cond;[
125 return nextConditionalToken();
129 return nextCDATAToken();
133 return nextDeclToken();
136 if (parsedtd || isInternal()) {
142 return nextTagToken();
160 case ICharacterScanner.EOF:
161 state = STATE_DEFAULT;
162 return getToken(null);
165 if (parsedtd || isInternal()) {
167 case ICharacterScanner.EOF:
168 state = STATE_DEFAULT;
169 return getToken(null);
183 state &= STATE_INTERNAL;
184 return getToken(isInternal() ? DTD_INTERNAL : null);
191 if (position == offset) {
197 return getToken(DTD_INTERNAL);
203 private IToken nextTagToken() {
207 case ICharacterScanner.EOF:
209 state = STATE_DEFAULT;
210 return getToken(XML_TAG);
218 return getToken(XML_ATTRIBUTE);
225 case ICharacterScanner.EOF:
226 state = STATE_DEFAULT;
227 return getToken(XML_ATTRIBUTE);
239 case ICharacterScanner.EOF:
241 state = STATE_DEFAULT;
242 return getToken(XML_TAG);
248 return getToken(XML_TAG);
253 private IToken nextDeclToken() {
256 case ICharacterScanner.EOF:
257 state = STATE_DEFAULT;
258 return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
261 if (parsedtd || isInternal()) {
263 case ICharacterScanner.EOF:
264 state = STATE_DEFAULT;
265 return getToken(isInternal() ? DTD_INTERNAL : null);
280 state &= STATE_INTERNAL;
281 return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
283 case '[': // <!DOCTYPE xxx [dtd]>
285 state = STATE_INTERNAL;
286 return getToken(XML_DECL);
292 private IToken nextCommentToken() {
293 state &= STATE_INTERNAL;
297 case ICharacterScanner.EOF:
302 case ICharacterScanner.EOF:
307 case ICharacterScanner.EOF:
318 return getToken(isInternal() ? DTD_INTERNAL_COMMENT : XML_COMMENT);
321 private IToken nextCDATAToken() {
322 state = STATE_DEFAULT;
327 case ICharacterScanner.EOF:
332 case ICharacterScanner.EOF:
337 case ICharacterScanner.EOF:
349 return getToken(XML_CDATA);
352 private IToken nextConditionalToken() {
353 state = STATE_DEFAULT;
360 case ICharacterScanner.EOF:
365 case ICharacterScanner.EOF:
370 case ICharacterScanner.EOF:
387 case ICharacterScanner.EOF:
392 case ICharacterScanner.EOF:
408 return getToken(DTD_CONDITIONAL);
411 private IToken getToken(String type) {
412 length = position - offset;
419 return Token.UNDEFINED;
422 IToken token = (IToken) tokens.get(type);
424 token = new Token(type);
425 tokens.put(type, token);
431 private boolean isInternal() {
432 return (state & STATE_INTERNAL) != 0;
436 if (position >= end) {
437 return ICharacterScanner.EOF;
441 return document.getChar(position++);
442 } catch (BadLocationException e) {
444 return ICharacterScanner.EOF;
448 private void unread() {
453 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
455 public int getTokenOffset() {
456 Assert.isTrue(offset>=0, Integer.toString(offset));
461 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
463 public int getTokenLength() {
468 * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int)
470 public void setRange(IDocument document, int offset, int length) {
471 this.document = document;
472 this.end = offset + length;
474 this.offset = offset;
475 this.position = offset;
478 this.state = STATE_DEFAULT;
482 * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
484 // public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
485 // state = STATE_DEFAULT;
486 // if (partitionOffset > -1) {
487 // int delta = offset - partitionOffset;
489 // setRange(document, partitionOffset, length + delta);
493 // setRange(document, partitionOffset, length);
496 * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
498 public void setPartialRange(
499 IDocument document, int offset, int length,
500 String contentType, int partitionOffset
502 // boolean flag = false;
503 this.document = document;
504 this.end = offset + length;
506 // NB! Undocumented value: -1
507 if (partitionOffset >= 0) {
508 offset = partitionOffset;
512 this.offset = offset;
513 this.position = offset;
517 // state = STATE_DEFAULT;
520 if (contentType == XML_ATTRIBUTE) {
525 if (contentType == XML_TAG) {
526 state = isContinuationPartition() ? STATE_TAG : STATE_DEFAULT;
530 if (contentType == XML_DECL) {
531 state = isContinuationPartition() ? STATE_DECL : STATE_DEFAULT;
535 if (contentType == DTD_INTERNAL ||
536 contentType == DTD_INTERNAL_DECL ||
537 contentType == DTD_INTERNAL_COMMENT
539 state = STATE_INTERNAL;
543 state = STATE_DEFAULT;
546 private boolean isContinuationPartition() {
548 String type = document.getContentType(offset - 1);
550 if (type != IDocument.DEFAULT_CONTENT_TYPE) {
553 } catch (BadLocationException e) {}