implemented Stepan's excellent suggestion of a cleaner computeNext() method on AbstractIterator to make a little easier to implement clean iterators - and avoid pesky nulls in the process
This commit is contained in:
@@ -14,13 +14,15 @@ public inline fun <T> iterate(nextFunction: () -> T?) : java.util.Iterator<T> =
|
|||||||
public inline fun <T, R: T> java.util.Iterator<T>.filterIsInstance(klass: Class<R>): java.util.Iterator<R> = FilterIsIterator<T,R>(this, klass)
|
public inline fun <T, R: T> java.util.Iterator<T>.filterIsInstance(klass: Class<R>): java.util.Iterator<R> = FilterIsIterator<T,R>(this, klass)
|
||||||
|
|
||||||
private class FilterIsIterator<T, R :T>(val iterator : java.util.Iterator<T>, val klass: Class<R>) : AbstractIterator<R>() {
|
private class FilterIsIterator<T, R :T>(val iterator : java.util.Iterator<T>, val klass: Class<R>) : AbstractIterator<R>() {
|
||||||
override protected fun computeNext(): R? {
|
override protected fun computeNext(): Unit {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val next = iterator.next()
|
val next = iterator.next()
|
||||||
if (klass.isInstance(next)) return next as R
|
if (klass.isInstance(next)) {
|
||||||
|
setNext(next as R)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done()
|
done()
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,13 +34,15 @@ private class FilterIsIterator<T, R :T>(val iterator : java.util.Iterator<T>, va
|
|||||||
public inline fun <T> java.util.Iterator<T>.filter(predicate: (T) -> Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, predicate)
|
public inline fun <T> java.util.Iterator<T>.filter(predicate: (T) -> Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, predicate)
|
||||||
|
|
||||||
private class FilterIterator<T>(val iterator : java.util.Iterator<T>, val predicate: (T)-> Boolean) : AbstractIterator<T>() {
|
private class FilterIterator<T>(val iterator : java.util.Iterator<T>, val predicate: (T)-> Boolean) : AbstractIterator<T>() {
|
||||||
override protected fun computeNext(): T? {
|
override protected fun computeNext(): Unit {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val next = iterator.next()
|
val next = iterator.next()
|
||||||
if ((predicate)(next)) return next
|
if ((predicate)(next)) {
|
||||||
|
setNext(next)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done()
|
done()
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,15 +53,17 @@ public inline fun <T> java.util.Iterator<T>.filterNot(predicate: (T) -> Boolean)
|
|||||||
public inline fun <T> java.util.Iterator<T?>?.filterNotNull() : java.util.Iterator<T> = FilterNotNullIterator(this)
|
public inline fun <T> java.util.Iterator<T?>?.filterNotNull() : java.util.Iterator<T> = FilterNotNullIterator(this)
|
||||||
|
|
||||||
private class FilterNotNullIterator<T>(val iterator : java.util.Iterator<T?>?) : AbstractIterator<T>() {
|
private class FilterNotNullIterator<T>(val iterator : java.util.Iterator<T?>?) : AbstractIterator<T>() {
|
||||||
override protected fun computeNext(): T? {
|
override protected fun computeNext(): Unit {
|
||||||
if (iterator != null) {
|
if (iterator != null) {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val next = iterator.next()
|
val next = iterator.next()
|
||||||
if (next != null) return next
|
if (next != null) {
|
||||||
|
setNext(next)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done()
|
done()
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +75,13 @@ private class FilterNotNullIterator<T>(val iterator : java.util.Iterator<T?>?) :
|
|||||||
public inline fun <T, R> java.util.Iterator<T>.map(transform: (T) -> R): java.util.Iterator<R> = MapIterator<T, R>(this, transform)
|
public inline fun <T, R> java.util.Iterator<T>.map(transform: (T) -> R): java.util.Iterator<R> = MapIterator<T, R>(this, transform)
|
||||||
|
|
||||||
private class MapIterator<T, R>(val iterator : java.util.Iterator<T>, val transform: (T) -> R) : AbstractIterator<R>() {
|
private class MapIterator<T, R>(val iterator : java.util.Iterator<T>, val transform: (T) -> R) : AbstractIterator<R>() {
|
||||||
override protected fun computeNext() : R? = if (iterator.hasNext()) (transform)(iterator.next()) else { done(); null }
|
override protected fun computeNext() : Unit {
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
setNext((transform)(iterator.next()))
|
||||||
|
} else {
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,14 +94,19 @@ public inline fun <T, R> java.util.Iterator<T>.flatMap(transform: (T) -> java.ut
|
|||||||
private class FlatMapIterator<T, R>(val iterator : java.util.Iterator<T>, val transform: (T) -> java.util.Iterator<R>) : AbstractIterator<R>() {
|
private class FlatMapIterator<T, R>(val iterator : java.util.Iterator<T>, val transform: (T) -> java.util.Iterator<R>) : AbstractIterator<R>() {
|
||||||
var transformed: java.util.Iterator<R> = iterate<R> { null }
|
var transformed: java.util.Iterator<R> = iterate<R> { null }
|
||||||
|
|
||||||
override protected fun computeNext() : R? {
|
override protected fun computeNext() : Unit {
|
||||||
if (transformed.hasNext()) return transformed.next()
|
while (true) {
|
||||||
if (iterator.hasNext()) {
|
if (transformed.hasNext()) {
|
||||||
transformed = (transform)(iterator.next())
|
setNext(transformed.next())
|
||||||
return computeNext()
|
return
|
||||||
|
}
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
transformed = (transform)(iterator.next())
|
||||||
|
} else {
|
||||||
|
done()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done()
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,13 +131,15 @@ public inline fun <T> java.util.Iterator<T>.take(n: Int): java.util.Iterator<T>
|
|||||||
public inline fun <T> java.util.Iterator<T>.takeWhile(predicate: (T) -> Boolean): java.util.Iterator<T> = TakeWhileIterator<T>(this, predicate)
|
public inline fun <T> java.util.Iterator<T>.takeWhile(predicate: (T) -> Boolean): java.util.Iterator<T> = TakeWhileIterator<T>(this, predicate)
|
||||||
|
|
||||||
private class TakeWhileIterator<T>(val iterator: java.util.Iterator<T>, val predicate: (T) -> Boolean) : AbstractIterator<T>() {
|
private class TakeWhileIterator<T>(val iterator: java.util.Iterator<T>, val predicate: (T) -> Boolean) : AbstractIterator<T>() {
|
||||||
override protected fun computeNext() : T? {
|
override protected fun computeNext() : Unit {
|
||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
val item = iterator.next()
|
val item = iterator.next()
|
||||||
if ((predicate)(item)) return item
|
if ((predicate)(item)) {
|
||||||
|
setNext(item)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done()
|
done()
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,3 +158,4 @@ public inline fun <T> java.util.Iterator<T>.join(separator: String = ", ", prefi
|
|||||||
if (limit != null && count > limit) buffer.append("...")
|
if (limit != null && count > limit) buffer.append("...")
|
||||||
return buffer.append(postfix).toString().sure()
|
return buffer.append(postfix).toString().sure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ set(value) {
|
|||||||
// Helper methods
|
// Helper methods
|
||||||
|
|
||||||
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
||||||
public fun Element.hasClass(cssClass: String): Boolean {
|
fun Element.hasClass(cssClass: String): Boolean {
|
||||||
val c = this.classes
|
val c = this.classes
|
||||||
return if (c != null)
|
return if (c != null)
|
||||||
c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
||||||
@@ -104,7 +104,7 @@ public fun Element.hasClass(cssClass: String): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the given CSS class to this element's 'class' attribute */
|
/** Adds the given CSS class to this element's 'class' attribute */
|
||||||
public fun Element.addClass(cssClass: String): Boolean {
|
fun Element.addClass(cssClass: String): Boolean {
|
||||||
val classSet = this.classSet
|
val classSet = this.classSet
|
||||||
val answer = classSet.add(cssClass)
|
val answer = classSet.add(cssClass)
|
||||||
if (answer) {
|
if (answer) {
|
||||||
@@ -114,7 +114,7 @@ public fun Element.addClass(cssClass: String): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the given CSS class to this element's 'class' attribute */
|
/** Removes the given CSS class to this element's 'class' attribute */
|
||||||
public fun Element.removeClass(cssClass: String): Boolean {
|
fun Element.removeClass(cssClass: String): Boolean {
|
||||||
val classSet = this.classSet
|
val classSet = this.classSet
|
||||||
val answer = classSet.remove(cssClass)
|
val answer = classSet.remove(cssClass)
|
||||||
if (answer) {
|
if (answer) {
|
||||||
@@ -125,7 +125,7 @@ public fun Element.removeClass(cssClass: String): Boolean {
|
|||||||
|
|
||||||
/** TODO this approach generates compiler errors...
|
/** TODO this approach generates compiler errors...
|
||||||
|
|
||||||
public fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
||||||
val set = this.classSet
|
val set = this.classSet
|
||||||
var answer = false
|
var answer = false
|
||||||
for (cs in cssClasses) {
|
for (cs in cssClasses) {
|
||||||
@@ -139,7 +139,7 @@ public fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
|||||||
return answer
|
return answer
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
||||||
val set = this.classSet
|
val set = this.classSet
|
||||||
var answer = false
|
var answer = false
|
||||||
for (cs in cssClasses) {
|
for (cs in cssClasses) {
|
||||||
@@ -155,7 +155,7 @@ public fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
||||||
public fun Document?.get(selector: String): List<Element> {
|
fun Document?.get(selector: String): List<Element> {
|
||||||
val root = this?.getDocumentElement()
|
val root = this?.getDocumentElement()
|
||||||
return if (root != null) {
|
return if (root != null) {
|
||||||
if (selector == "*") {
|
if (selector == "*") {
|
||||||
@@ -179,7 +179,7 @@ public fun Document?.get(selector: String): List<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
||||||
public fun Element.get(selector: String): List<Element> {
|
fun Element.get(selector: String): List<Element> {
|
||||||
return if (selector == "*") {
|
return if (selector == "*") {
|
||||||
elements
|
elements
|
||||||
} else if (selector.startsWith(".")) {
|
} else if (selector.startsWith(".")) {
|
||||||
@@ -197,57 +197,53 @@ public fun Element.get(selector: String): List<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an [[Iterator]] over the next siblings of this node */
|
/** Returns an [[Iterator]] over the next siblings of this node */
|
||||||
public fun Node.nextSiblings() : Iterator<Node> = NextSiblingIterator(this)
|
fun Node.nextSiblings() : Iterator<Node> = NextSiblingIterator(this)
|
||||||
|
|
||||||
class NextSiblingIterator(var node: Node) : AbstractIterator<Node>() {
|
class NextSiblingIterator(var node: Node) : AbstractIterator<Node>() {
|
||||||
|
|
||||||
public override fun computeNext(): Node? {
|
override fun computeNext(): Unit {
|
||||||
val next = node.getNextSibling()
|
val next = node.getNextSibling()
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
node = next
|
setNext(next)
|
||||||
return next
|
|
||||||
} else {
|
} else {
|
||||||
done()
|
done()
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Returns an [[Iterator]] over the next siblings of this node */
|
/** Returns an [[Iterator]] over the next siblings of this node */
|
||||||
public fun Node.previousSiblings() : Iterator<Node> = PreviousSiblingIterator(this)
|
fun Node.previousSiblings() : Iterator<Node> = PreviousSiblingIterator(this)
|
||||||
|
|
||||||
class PreviousSiblingIterator(var node: Node) : AbstractIterator<Node>() {
|
class PreviousSiblingIterator(var node: Node) : AbstractIterator<Node>() {
|
||||||
|
|
||||||
public override fun computeNext(): Node? {
|
override fun computeNext(): Unit {
|
||||||
val next = node.getPreviousSibling()
|
val next = node.getPreviousSibling()
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
node = next
|
setNext(next)
|
||||||
return next
|
|
||||||
} else {
|
} else {
|
||||||
done()
|
done()
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if this node is a Text node or a CDATA node */
|
/** Returns true if this node is a Text node or a CDATA node */
|
||||||
public fun Node.isText(): Boolean {
|
fun Node.isText(): Boolean {
|
||||||
val nodeType = getNodeType()
|
val nodeType = getNodeType()
|
||||||
return nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
|
return nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an [[Iterator]] of all the next [[Element]] siblings */
|
/** Returns an [[Iterator]] of all the next [[Element]] siblings */
|
||||||
public fun Node.nextElements(): Iterator<Element> = nextSiblings().filterIsInstance<Node, Element>(javaClass<Element>())
|
fun Node.nextElements(): Iterator<Element> = nextSiblings().filterIsInstance<Node, Element>(javaClass<Element>())
|
||||||
|
|
||||||
/** Returns an [[Iterator]] of all the previous [[Element]] siblings */
|
/** Returns an [[Iterator]] of all the previous [[Element]] siblings */
|
||||||
public fun Node.previousElements(): Iterator<Element> = previousSiblings().filterIsInstance<Node, Element>(javaClass<Element>())
|
fun Node.previousElements(): Iterator<Element> = previousSiblings().filterIsInstance<Node, Element>(javaClass<Element>())
|
||||||
|
|
||||||
/** Returns the attribute value or empty string if its not present */
|
/** Returns the attribute value or empty string if its not present */
|
||||||
public inline fun Element.attribute(name: String): String {
|
inline fun Element.attribute(name: String): String {
|
||||||
return this.getAttribute(name) ?: ""
|
return this.getAttribute(name) ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the children of the element as a list */
|
/** Returns the children of the element as a list */
|
||||||
public inline fun Element?.children(): List<Node> {
|
inline fun Element?.children(): List<Node> {
|
||||||
return this?.getChildNodes().toList()
|
return this?.getChildNodes().toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,22 +257,22 @@ get() = this?.getElementsByTagName("*").toElementList()
|
|||||||
|
|
||||||
|
|
||||||
/** Returns all the child elements given the local element name */
|
/** Returns all the child elements given the local element name */
|
||||||
public inline fun Element?.elements(localName: String?): List<Element> {
|
inline fun Element?.elements(localName: String?): List<Element> {
|
||||||
return this?.getElementsByTagName(localName).toElementList()
|
return this?.getElementsByTagName(localName).toElementList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all the elements given the local element name */
|
/** Returns all the elements given the local element name */
|
||||||
public inline fun Document?.elements(localName: String?): List<Element> {
|
inline fun Document?.elements(localName: String?): List<Element> {
|
||||||
return this?.getElementsByTagName(localName).toElementList()
|
return this?.getElementsByTagName(localName).toElementList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all the child elements given the namespace URI and local element name */
|
/** Returns all the child elements given the namespace URI and local element name */
|
||||||
public inline fun Element?.elements(namespaceUri: String?, localName: String?): List<Element> {
|
inline fun Element?.elements(namespaceUri: String?, localName: String?): List<Element> {
|
||||||
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all the elements given the namespace URI and local element name */
|
/** Returns all the elements given the namespace URI and local element name */
|
||||||
public inline fun Document?.elements(namespaceUri: String?, localName: String?): List<Element> {
|
inline fun Document?.elements(namespaceUri: String?, localName: String?): List<Element> {
|
||||||
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +296,7 @@ val NodeList?.last : Node?
|
|||||||
get() = this.tail
|
get() = this.tail
|
||||||
|
|
||||||
|
|
||||||
public inline fun NodeList?.toList(): List<Node> {
|
inline fun NodeList?.toList(): List<Node> {
|
||||||
return if (this == null) {
|
return if (this == null) {
|
||||||
Collections.EMPTY_LIST as List<Node>
|
Collections.EMPTY_LIST as List<Node>
|
||||||
}
|
}
|
||||||
@@ -309,7 +305,7 @@ public inline fun NodeList?.toList(): List<Node> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun NodeList?.toElementList(): List<Element> {
|
inline fun NodeList?.toElementList(): List<Element> {
|
||||||
return if (this == null) {
|
return if (this == null) {
|
||||||
Collections.EMPTY_LIST as List<Element>
|
Collections.EMPTY_LIST as List<Element>
|
||||||
}
|
}
|
||||||
@@ -319,7 +315,7 @@ public inline fun NodeList?.toElementList(): List<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Converts the node list to an XML String */
|
/** Converts the node list to an XML String */
|
||||||
public fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String {
|
fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String {
|
||||||
return if (this == null)
|
return if (this == null)
|
||||||
"" else {
|
"" else {
|
||||||
nodesToXmlString(this.toList(), xmlDeclaration)
|
nodesToXmlString(this.toList(), xmlDeclaration)
|
||||||
@@ -327,7 +323,7 @@ public fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() {
|
class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() {
|
||||||
public override fun get(index: Int): Node {
|
override fun get(index: Int): Node {
|
||||||
val node = nodeList.item(index)
|
val node = nodeList.item(index)
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index)
|
throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index)
|
||||||
@@ -336,11 +332,11 @@ class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun size(): Int = nodeList.getLength()
|
override fun size(): Int = nodeList.getLength()
|
||||||
}
|
}
|
||||||
|
|
||||||
class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() {
|
class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() {
|
||||||
public override fun get(index: Int): Element {
|
override fun get(index: Int): Element {
|
||||||
val node = nodeList.item(index)
|
val node = nodeList.item(index)
|
||||||
if (node is Element) {
|
if (node is Element) {
|
||||||
return node
|
return node
|
||||||
@@ -353,23 +349,23 @@ class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun size(): Int = nodeList.getLength()
|
override fun size(): Int = nodeList.getLength()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Syntax sugar
|
// Syntax sugar
|
||||||
|
|
||||||
public inline fun Node.plus(child: Node?): Node {
|
inline fun Node.plus(child: Node?): Node {
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
this.appendChild(child)
|
this.appendChild(child)
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun Element.plus(text: String?): Element = this.addText(text)
|
inline fun Element.plus(text: String?): Element = this.addText(text)
|
||||||
|
|
||||||
public inline fun Element.plusAssign(text: String?): Element = this.addText(text)
|
inline fun Element.plusAssign(text: String?): Element = this.addText(text)
|
||||||
|
|
||||||
|
|
||||||
// Builder
|
// Builder
|
||||||
@@ -377,7 +373,7 @@ public inline fun Element.plusAssign(text: String?): Element = this.addText(text
|
|||||||
/**
|
/**
|
||||||
* Creates a new element which can be configured via a function
|
* Creates a new element which can be configured via a function
|
||||||
*/
|
*/
|
||||||
public fun Document.createElement(name: String, init: Element.()-> Unit): Element {
|
fun Document.createElement(name: String, init: Element.()-> Unit): Element {
|
||||||
val elem = this.createElement(name).sure()
|
val elem = this.createElement(name).sure()
|
||||||
elem.init()
|
elem.init()
|
||||||
return elem
|
return elem
|
||||||
@@ -386,14 +382,14 @@ public fun Document.createElement(name: String, init: Element.()-> Unit): Elemen
|
|||||||
/**
|
/**
|
||||||
* Creates a new element to an element which has an owner Document which can be configured via a function
|
* Creates a new element to an element which has an owner Document which can be configured via a function
|
||||||
*/
|
*/
|
||||||
public fun Element.createElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element {
|
fun Element.createElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element {
|
||||||
val elem = ownerDocument(doc).createElement(name).sure()
|
val elem = ownerDocument(doc).createElement(name).sure()
|
||||||
elem.init()
|
elem.init()
|
||||||
return elem
|
return elem
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the owner document of the element or uses the provided document */
|
/** Returns the owner document of the element or uses the provided document */
|
||||||
public fun Node.ownerDocument(doc: Document? = null): Document {
|
fun Node.ownerDocument(doc: Document? = null): Document {
|
||||||
val answer = if (this is Document) this as Document
|
val answer = if (this is Document) this as Document
|
||||||
else if (doc == null) this.getOwnerDocument()
|
else if (doc == null) this.getOwnerDocument()
|
||||||
else doc
|
else doc
|
||||||
@@ -408,7 +404,7 @@ public fun Node.ownerDocument(doc: Document? = null): Document {
|
|||||||
/**
|
/**
|
||||||
Adds a newly created element which can be configured via a function
|
Adds a newly created element which can be configured via a function
|
||||||
*/
|
*/
|
||||||
public fun Document.addElement(name: String, init: Element.()-> Unit): Element {
|
fun Document.addElement(name: String, init: Element.()-> Unit): Element {
|
||||||
val child = createElement(name, init)
|
val child = createElement(name, init)
|
||||||
this.appendChild(child)
|
this.appendChild(child)
|
||||||
return child
|
return child
|
||||||
@@ -417,7 +413,7 @@ public fun Document.addElement(name: String, init: Element.()-> Unit): Element {
|
|||||||
/**
|
/**
|
||||||
Adds a newly created element to an element which has an owner Document which can be configured via a function
|
Adds a newly created element to an element which has an owner Document which can be configured via a function
|
||||||
*/
|
*/
|
||||||
public fun Element.addElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element {
|
fun Element.addElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element {
|
||||||
val child = createElement(name, doc, init)
|
val child = createElement(name, doc, init)
|
||||||
this.appendChild(child)
|
this.appendChild(child)
|
||||||
return child
|
return child
|
||||||
@@ -426,7 +422,7 @@ public fun Element.addElement(name: String, doc: Document? = null, init: Element
|
|||||||
/**
|
/**
|
||||||
Adds a newly created text node to an element which either already has an owner Document or one must be provided as a parameter
|
Adds a newly created text node to an element which either already has an owner Document or one must be provided as a parameter
|
||||||
*/
|
*/
|
||||||
public fun Element.addText(text: String?, doc: Document? = null): Element {
|
fun Element.addText(text: String?, doc: Document? = null): Element {
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
val child = ownerDocument(doc).createTextNode(text)
|
val child = ownerDocument(doc).createTextNode(text)
|
||||||
this.appendChild(child)
|
this.appendChild(child)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package kotlin.support
|
|||||||
|
|
||||||
import java.util.NoSuchElementException
|
import java.util.NoSuchElementException
|
||||||
|
|
||||||
public enum class State {
|
enum class State {
|
||||||
Ready
|
Ready
|
||||||
NotReady
|
NotReady
|
||||||
Done
|
Done
|
||||||
@@ -14,10 +14,10 @@ public enum class State {
|
|||||||
* to implement the iterator, calling [[done()]] when the iteration is complete.
|
* to implement the iterator, calling [[done()]] when the iteration is complete.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractIterator<T>: java.util.Iterator<T> {
|
public abstract class AbstractIterator<T>: java.util.Iterator<T> {
|
||||||
public var state: State = State.NotReady
|
private var state: State = State.NotReady
|
||||||
public var next: T? = null
|
private var next: T? = null
|
||||||
|
|
||||||
public override fun hasNext(): Boolean {
|
override fun hasNext(): Boolean {
|
||||||
require(state != State.Failed)
|
require(state != State.Failed)
|
||||||
return when (state) {
|
return when (state) {
|
||||||
State.Done -> false
|
State.Done -> false
|
||||||
@@ -26,13 +26,13 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun next(): T {
|
override fun next(): T {
|
||||||
if (!hasNext()) throw NoSuchElementException()
|
if (!hasNext()) throw NoSuchElementException()
|
||||||
state = State.NotReady
|
state = State.NotReady
|
||||||
return next.sure()
|
return next.sure()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun remove() { throw UnsupportedOperationException() }
|
override fun remove() { throw UnsupportedOperationException() }
|
||||||
|
|
||||||
/** Returns the next element in the iteration without advancing the iteration */
|
/** Returns the next element in the iteration without advancing the iteration */
|
||||||
fun peek(): T {
|
fun peek(): T {
|
||||||
@@ -42,14 +42,33 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
|
|||||||
|
|
||||||
private fun tryToComputeNext(): Boolean {
|
private fun tryToComputeNext(): Boolean {
|
||||||
state = State.Failed
|
state = State.Failed
|
||||||
next = computeNext();
|
computeNext();
|
||||||
return if (state != State.Done) { state = State.Ready; true } else false
|
return state == State.Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Computes the next element in the iterator, calling [[done()]] when there are no more elements */
|
/**
|
||||||
abstract protected fun computeNext(): T?
|
* Computes the next item in the iterator.
|
||||||
|
*
|
||||||
|
* This callback method should call one of these two methods
|
||||||
|
*
|
||||||
|
* * [[setNext(T)]] with the next value of the iteration
|
||||||
|
* * [[done()]] to indicate there are no more elements
|
||||||
|
*
|
||||||
|
* Failure to call either method will result in the iteration terminating with a failed state
|
||||||
|
*/
|
||||||
|
abstract protected fun computeNext(): Unit
|
||||||
|
|
||||||
/** Sets the state to done so that the iteration terminates */
|
/**
|
||||||
|
* Sets the next value in the iteration, called from the [[computeNext()]] function
|
||||||
|
*/
|
||||||
|
protected fun setNext(value: T): Unit {
|
||||||
|
next = value
|
||||||
|
state = State.Ready
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state to done so that the iteration terminates
|
||||||
|
*/
|
||||||
protected fun done() {
|
protected fun done() {
|
||||||
state = State.Done
|
state = State.Done
|
||||||
}
|
}
|
||||||
@@ -58,9 +77,12 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
|
|||||||
/** An [[Iterator]] which invokes a function to calculate the next value in the iteration until the function returns *null* */
|
/** An [[Iterator]] which invokes a function to calculate the next value in the iteration until the function returns *null* */
|
||||||
class FunctionIterator<T>(val nextFunction : () -> T?) : AbstractIterator<T>() {
|
class FunctionIterator<T>(val nextFunction : () -> T?) : AbstractIterator<T>() {
|
||||||
|
|
||||||
override protected fun computeNext(): T? {
|
override protected fun computeNext(): Unit {
|
||||||
val next = (nextFunction)()
|
val next = (nextFunction)()
|
||||||
if (next == null) done()
|
if (next == null) {
|
||||||
return next
|
done()
|
||||||
|
} else {
|
||||||
|
setNext(next)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user