You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlbeans.apache.org by ce...@apache.org on 2008/04/04 00:36:55 UTC
svn commit: r644535 - in /xmlbeans/trunk/src:
store/org/apache/xmlbeans/impl/store/ xmlpublic/org/apache/xmlbeans/
Author: cezar
Date: Thu Apr 3 15:36:47 2008
New Revision: 644535
URL: http://svn.apache.org/viewvc?rev=644535&view=rev
Log:
Implementation of much requested fine grained CDATA feature.
checkintests pass
Added:
xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java
Modified:
xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Cur.java
xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Locale.java
xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Saver.java
xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Xobj.java
xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
Modified: xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Cur.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Cur.java?rev=644535&r1=644534&r2=644535&view=diff
==============================================================================
--- xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Cur.java (original)
+++ xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Cur.java Thu Apr 3 15:36:47 2008
@@ -74,6 +74,7 @@
import org.apache.xmlbeans.impl.store.DomImpl.SaajTextNode;
import org.apache.xmlbeans.impl.store.DomImpl.SaajCdataNode;
+import org.apache.xmlbeans.CDataBookmark;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.SchemaField;
@@ -170,6 +171,8 @@
boolean isNormalAttr ( ) { return isNode() && _xobj.isNormalAttr(); }
boolean isXmlns ( ) { return isNode() && _xobj.isXmlns(); }
+
+ boolean isTextCData ( ) { return _xobj.hasBookmark(CDataBookmark.class, _pos); }
QName getName ( ) { assert isNode() || isEnd(); return _xobj._name; }
String getLocal ( ) { return getName().getLocalPart(); }
Modified: xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Locale.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Locale.java?rev=644535&r1=644534&r2=644535&view=diff
==============================================================================
--- xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Locale.java (original)
+++ xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Locale.java Thu Apr 3 15:36:47 2008
@@ -83,6 +83,7 @@
import org.apache.xmlbeans.impl.store.Cur.Locations;
+import org.apache.xmlbeans.CDataBookmark;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.XmlCursor;
@@ -3167,6 +3168,9 @@
_wantLineNumbersAtEndElt =
_startLocator != null &&
options.hasOption(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT);
+ _wantCdataBookmarks =
+ _startLocator != null &&
+ options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS);
}
public void startDocument()
@@ -3281,6 +3285,8 @@
throws SAXException
{
_context.text(ch, start, length);
+ if (_wantCdataBookmarks && _insideCDATA)
+ _context.bookmarkLastNonAttr(CDataBookmark.CDATA_BOOKMARK);
}
public void ignorableWhitespace(char ch[], int start, int length)
@@ -3341,11 +3347,13 @@
public void startCDATA()
throws SAXException
{
+ _insideCDATA = true;
}
public void endCDATA()
throws SAXException
{
+ _insideCDATA = false;
}
public void startEntity(String name)
@@ -3388,7 +3396,9 @@
private boolean _wantLineNumbers;
private boolean _wantLineNumbersAtEndElt;
+ private boolean _wantCdataBookmarks;
private Locator _startLocator;
+ private boolean _insideCDATA = false;
}
private static abstract class SaxLoader
Modified: xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Saver.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Saver.java?rev=644535&r1=644534&r2=644535&view=diff
==============================================================================
--- xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Saver.java (original)
+++ xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Saver.java Thu Apr 3 15:36:47 2008
@@ -904,6 +904,9 @@
if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD))
_cdataEntityCountThreshold = ((Integer)options.get(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD)).intValue();
+ if (options != null && options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS) )
+ _useCDataBookmarks = true;
+
_in = _out = 0;
_free = 0;
@@ -1010,9 +1013,12 @@
{
assert c.isText();
+ // c.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
+ boolean forceCData = _useCDataBookmarks && c.isTextCData();
+
emit( c );
- entitizeContent();
+ entitizeContent( forceCData );
}
protected void emitComment ( SaveCur c )
@@ -1304,7 +1310,7 @@
return false;
}
- private void entitizeContent ( )
+ private void entitizeContent ( boolean forceCData )
{
assert _free >=0;
@@ -1337,7 +1343,7 @@
prevChar = ch;
}
- if (count == 0 && !hasCharToBeReplaced && count<_cdataEntityCountThreshold)
+ if (!forceCData && count == 0 && !hasCharToBeReplaced && count<_cdataEntityCountThreshold)
return;
i = _lastEmitIn;
@@ -1345,7 +1351,7 @@
//
// Heuristic for knowing when to save out stuff as a CDATA.
//
- if (_lastEmitCch > _cdataLengthThreshold && count > _cdataEntityCountThreshold)
+ if (forceCData || (_lastEmitCch > _cdataLengthThreshold && count > _cdataEntityCountThreshold) )
{
boolean lastWasBracket = _buf[ i ] == ']';
@@ -1842,6 +1848,7 @@
private static final int _initialBufSize = 4096;
private int _cdataLengthThreshold = 32;
private int _cdataEntityCountThreshold = 5;
+ private boolean _useCDataBookmarks = false;
private int _lastEmitIn;
private int _lastEmitCch;
@@ -3662,6 +3669,7 @@
abstract boolean hasChildren ( );
abstract boolean hasText ( );
+ abstract boolean isTextCData ( );
abstract boolean toFirstAttr ( );
abstract boolean toNextAttr ( );
@@ -3708,6 +3716,7 @@
boolean hasChildren ( ) { return _cur.hasChildren(); }
boolean hasText ( ) { return _cur.hasText(); }
+ boolean isTextCData ( ) { return _cur.isTextCData(); }
boolean toFirstAttr ( ) { return _cur.toFirstAttr(); }
boolean toNextAttr ( ) { return _cur.toNextAttr(); }
@@ -3763,6 +3772,7 @@
boolean hasChildren ( ) { return _cur.hasChildren(); }
boolean hasText ( ) { return _cur.hasText(); }
+ boolean isTextCData ( ) { return _cur.isTextCData(); }
boolean toFirstAttr ( ) { return _cur.toFirstAttr(); }
boolean toNextAttr ( ) { return _cur.toNextAttr(); }
@@ -3975,6 +3985,11 @@
return hasText;
}
+ boolean isTextCData ( )
+ {
+ return _cur.isTextCData();
+ }
+
Object getChars ( )
{
assert _state == CUR && _cur.isText();
@@ -4159,6 +4174,11 @@
_prettyOffset =
((Integer) options.get( XmlOptions.SAVE_PRETTY_PRINT_OFFSET )).intValue();
}
+
+ if (options.hasOption( XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS ))
+ {
+ _useCDataBookmarks = true;
+ }
}
List getAncestorNamespaces ( ) { return _cur.getAncestorNamespaces(); }
@@ -4176,6 +4196,10 @@
boolean hasChildren ( ) { return _txt == null ? _cur.hasChildren() : false; }
boolean hasText ( ) { return _txt == null ? _cur.hasText() : false; }
+ // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
+ boolean isTextCData ( ) { return _txt == null ? (_useCDataBookmarks && _cur.isTextCData())
+ : _isTextCData; }
+
boolean toFirstAttr ( ) { assert _txt == null; return _cur.toFirstAttr(); }
boolean toNextAttr ( ) { assert _txt == null; return _cur.toNextAttr(); }
String getAttrValue ( ) { assert _txt == null; return _cur.getAttrValue(); }
@@ -4198,6 +4222,7 @@
assert _txt.length() > 0;
assert !_cur.isText();
_txt = null;
+ _isTextCData = false;
k = _cur.kind();
}
else
@@ -4214,6 +4239,8 @@
// place any text encountered in the buffer
if (_cur.isText())
{
+ // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
+ _isTextCData = _useCDataBookmarks && _cur.isTextCData();
CharUtil.getString( _sb, _cur.getChars(), _cur._offSrc, _cur._cchSrc );
_cur.next();
trim( _sb );
@@ -4263,6 +4290,7 @@
_cur.push();
_stack.add( _txt );
_stack.add( new Integer( _depth ) );
+ _isTextCData = false;
}
void pop ( )
@@ -4270,6 +4298,7 @@
_cur.pop();
_depth = ((Integer) _stack.remove( _stack.size() - 1 )).intValue();
_txt = (String) _stack.remove( _stack.size() - 1 );
+ _isTextCData = false;
}
Object getChars ( )
@@ -4325,6 +4354,8 @@
private int _depth;
private ArrayList _stack;
+ private boolean _isTextCData = false;
+ private boolean _useCDataBookmarks = false;
}
Modified: xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Xobj.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Xobj.java?rev=644535&r1=644534&r2=644535&view=diff
==============================================================================
--- xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Xobj.java (original)
+++ xmlbeans/trunk/src/store/org/apache/xmlbeans/impl/store/Xobj.java Thu Apr 3 15:36:47 2008
@@ -492,6 +492,18 @@
return b;
}
+ final boolean hasBookmark(Object key, int pos)
+ {
+ for ( Bookmark b = _bookmarks ; b != null ; b = b._next )
+ if ( b._pos == pos && key == b._key )
+ {
+ //System.out.println("hasCDataBookmark pos: " + pos + " xobj: " + getQName() + " b._pos: " + _bookmarks._pos);
+ return true;
+ }
+
+ return false;
+ }
+
final Xobj findXmlnsForPrefix ( String prefix )
{
assert isContainer() && prefix != null;
Added: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java?rev=644535&view=auto
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java (added)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java Thu Apr 3 15:36:47 2008
@@ -0,0 +1,58 @@
+/* Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.xmlbeans;
+
+/**
+ * Represents a CDATA bookmark.
+ *
+ * <p>When XmlOption UseCDataBookmarks is setted on parse methods,
+ * the loader will set these CDataBookmarks in the store on the respective
+ * TEXT fields that were represented as CDATA.</p>
+ *
+ * <p>Users can modify the 'look' of TEXT fields, by annotating them with
+ * this bookmark, or remove the bookmark.</p>
+ *
+ * <p>Additionaly if setted on save methods, the output will look for these
+ * bookmarks and will output the text as CDATA.
+ * Note: The SaveCDataEntityCountThreshold and SaveCDataLengthThreshold
+ * options and their default values still apply.</p>
+ *
+ * <p>Note: Due to the store representation, a CDATA will not be recognized
+ * if it is imediately after non CDATA text and all text following it will
+ * be considered CDATA.<br/>
+ * Example:<br>
+ * <pre>
+ * <a><![CDATA[cdata text]]></a> - is considered as: <a><![CDATA[cdata text]]></a>
+ * <b><![CDATA[cdata text]]> regular text</b> - is considered as: <b><![CDATA[cdata text regular text]]></b>
+ * <c>text <![CDATA[cdata text]]></c> - is considered as: <c>text cdata text</c>
+ * </pre>
+ * </p>
+ * @see XmlOptions#setUseCDataBookmarks()
+ * @see org.apache.xmlbeans.XmlObject.Factory#parse(String, XmlOptions)
+ * @see org.apache.xmlbeans.XmlObject#save(java.io.OutputStream, XmlOptions)
+ * @see XmlOptions#setSaveCDataEntityCountThreshold(int)
+ * @see XmlOptions#setSaveCDataLengthThreshold(int)
+ * @author Cezar Andrei (cezar dot andrei at gmail dot com)
+ */
+public class CDataBookmark
+ extends XmlCursor.XmlBookmark
+{
+ /**
+ * The actual bookmark object representing CData.<br>
+ * Users must use this bookmark in addition to UseCDataBookmarks
+ * option to make use of CDATA representation in XML text.
+ */
+ public static CDataBookmark CDATA_BOOKMARK = new CDataBookmark();
+}
\ No newline at end of file
Modified: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java?rev=644535&r1=644534&r2=644535&view=diff
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java (original)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java Thu Apr 3 15:36:47 2008
@@ -401,6 +401,57 @@
}
/**
+ * <p>Use this option when parsing and saving XML documents.</p>
+ *
+ * <p>For parsing this option will annotate the text fields in the store with CDataBookmark.</p>
+ *
+ * <p>For saving this option will save the text fields annotated with CDataBookmark as
+ * CDATA XML text.<br>
+ * Note: The SaveCDataEntityCountThreshold and SaveCDataLengthThreshold options and
+ * their default values still apply.</p>
+ *
+ * <p><b>Note: Due to the store representation, a CDATA will not be recognized
+ * if it is imediately after non CDATA text and all text following it will
+ * be considered CDATA.</b><br/>
+ * Example:<br>
+ * <pre>
+ * <a><![CDATA[cdata text]]></a> - is considered as: <a><![CDATA[cdata text]]></a>
+ * <b><![CDATA[cdata text]]> regular text</b> - is considered as: <b><![CDATA[cdata text regular text]]></b>
+ * <c>text <![CDATA[cdata text]]></c> - is considered as: <c>text cdata text</c>
+ * </pre>
+ * </p>
+ *
+ * <p>Sample code:
+ * <pre>
+ String xmlText = "<a>\n" +
+ "<a><![CDATA[cdata text]]></a>\n" +
+ "<b><![CDATA[cdata text]]> regular text</b>\n" +
+ "<c>text <![CDATA[cdata text]]></c>\n" +
+ "</a>";
+ System.out.println(xmlText);
+
+ XmlOptions opts = new XmlOptions();
+ opts.setUseCDataBookmarks();
+
+ XmlObject xo = XmlObject.Factory.parse( xmlText , opts);
+
+ System.out.println("xo1:\n" + xo.xmlText(opts));
+ System.out.println("\n");
+
+ opts.setSavePrettyPrint();
+ System.out.println("xo2:\n" + xo.xmlText(opts));
+ * </pre>
+ * </p>
+ *
+ * @see CDataBookmark
+ * @see CDataBookmark#CDATA_BOOKMARK
+ */
+ public XmlOptions setUseCDataBookmarks()
+ {
+ return set( LOAD_SAVE_CDATA_BOOKMARKS );
+ }
+
+ /**
* This option controls whether namespace declarations are included as attributes in the
* startElement event. By default, up to and including XMLBeans 2.3.0 they were included, in
* subsequent versions, they are no longer included.
@@ -832,8 +883,9 @@
/** @exclude */
public static final String LOAD_LINE_NUMBERS = "LOAD_LINE_NUMBERS";
/** @exclude */
- public static final String LOAD_LINE_NUMBERS_END_ELEMENT= "LOAD_LINE_NUMBERS_END_ELEMENT";
-
+ public static final String LOAD_LINE_NUMBERS_END_ELEMENT = "LOAD_LINE_NUMBERS_END_ELEMENT";
+ /** @exclude */
+ public static final String LOAD_SAVE_CDATA_BOOKMARKS = "LOAD_SAVE_CDATA_BOOKMARKS";
/** @exclude */
public static final String LOAD_SUBSTITUTE_NAMESPACES = "LOAD_SUBSTITUTE_NAMESPACES";
/** @exclude */
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: commits-help@xmlbeans.apache.org