Ranides Atterwim 3 år sedan
förälder
incheckning
6360539b3e

+ 453 - 51
assira.core/src/main/java/net/ranides/assira/xml/XMLElement.java

@@ -105,10 +105,30 @@ public interface XMLElement extends Wrapper<String> {
         return W3ElementFactory.fromStream(doc);
     }
 
+    /**
+     * Returns document which owns this element
+     *
+     * This method does not return root node of XML document.
+     * To obtain root element, please use {@link #root}
+     *
+     * @return XMLDocument
+     */
     XMLDocument document();
-    
+
+    /**
+     * Returns root parent of this element
+     * If this element is root, returns it.
+     *
+     * @return XMLElement
+     */
     XMLElement root();
-    
+
+    /**
+     * Returns type of this element.
+     * For example XMLElement can represent attribute, tag, or text fragment.
+     *
+     * @return XMLType
+     */
     XMLType nodetype();
 
     /**
@@ -117,101 +137,483 @@ public interface XMLElement extends Wrapper<String> {
      * @return this
      */
     Node node();
-    
+
+    /**
+     * Returns name of this element.
+     *
+     * Please note that different node types return different results:
+     * 		ELEMENT         tag name
+     * 		ATTRIBUTE       attribute name
+     *
+     * 		ENTITY          name of entity
+     * 		REFERENCE       name of referenced entity
+     * 		PROCESSING      processing instruction target
+     * 		DOCTYPE         doctype name
+     * 		NOTATION        notation name
+     *
+     * 		DOCUMENT        "#document"
+     * 		FRAGMENT        "#document-fragment"
+     * 		TEXT            "#text"
+     * 		CDATA           "#cdata-section"
+     * 		COMMENT         "#comment"
+     *
+     * @return String
+     */
     String name();
-    
+
+    /**
+     * Returns XPATH to this element
+     *
+     * @return String
+     */
     String xpath();
-    
+
+    /**
+     * Returns content of this element
+     *
+     * Please note that different node types return different results:
+     *		ELEMENT         null!
+     *
+     * 		ATTRIBUTE       attribute value
+     * 		TEXT            content of text node
+     * 		COMMENT         content of the comment
+     * 		CDATA           content of CDATA section
+     * 	    PROCESSING      content of processing instruction
+     *
+     * 		ENTITY          null
+     * 		REFERENCE       null
+     * 		DOCTYPE         null
+     * 		NOTATION        null
+     * 		DOCUMENT        null
+     * 		FRAGMENT        null
+     *
+     * @return String
+     */
     String content();
-    
+
+    /**
+     * Returns text content inside this element.
+     *
+     * If this node returns non-null content, then it is returned.
+     * Otherwise, it returns concatenation of "text" from all child nodes.
+     * It returns empty string, if it has no children.
+     *
+     * Exceptions:
+     *      DOCUMENT and NOTATION will return null!
+     *
+     * @return String or null
+     */
     String text();
-    
+
+    /**
+     * Returns all attributes of this elements, as XMLElements collection.
+     *
+     * XMLElements is universal collection.
+     * You can use it to process list of attributes, tag elements or comment sections.
+     *
+     * @return XMLElements
+     */
     XMLElements attrs();
-    
+
+    /**
+     * Returns first attribute with specified name
+     *
+     * Throws NoSuchElementException if there is no attribute.
+     *
+     * @param name name
+     * @return XMLElement
+     */
     XMLElement attr(String name);
-    
-    
-    
+
+    /**
+     * Compiles provided expression to XMLSelector and returns elements matched by it.
+     *
+     * Generally, this method searches recursively for any matching element.
+     * If you want to select only direct children matching provided expression, lets use {@link #children(String)}
+     *
+     * Returns empty collection if there is no matching elements.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements find(String selector);
-    
+
+    /**
+     * Returns elements matched by provided XMLSelector.
+     *
+     * Generally, this method searches recursively for any matching element.
+     * If you want to select only direct children matching provided expression, lets use {@link #children(Predicate)}
+     *
+     * Returns empty collection if there is no matching elements.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements find(XMLSelector selector);
-    
+
+    /**
+     * Returns list of direct children
+     *
+     * Returns empty collection element does not have children.
+     *
+     * @return XMLElements
+     */
     XMLElements children();
-    
+
+    /**
+     * Returns list of direct children filtered by provided selector.
+     *
+     * This method does not search recursively.
+     * If you want to search recursively for any matching element, lets use {@link #find(String)}
+     *
+     * Returns empty collection if there is no matching children.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements children(String selector);
-    
+
+    /**
+     * Returns list of direct children filtered by provided predicate.
+     *
+     * This method does not search recursively.
+     * If you want to search recursively for any matching element,
+     * and your selector is XMLSelector, you can use {@link #find(XMLSelector)}.
+     *
+     * There is no way to recursively scan by predicate.
+     *
+     * @todo xml: implement recursive scan by predicate
+     *      in fact it should be just "find(Predicate)" which
+     *      internally runs recursive traversal
+     *      or runs "find(XMLSelector)" if predicate is XMLSelector
+     *
+     * Returns empty collection if there is no matching children.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements children(Predicate<XMLContext> selector);
-    
+
+    /**
+     * Returns true, if this element has any children
+     *
+     * @return boolean
+     */
     boolean has();
-    
+
+    /**
+     * Returns true, if this element has any direct child matching selector
+     *
+     * There is no method to make recursive check, but you can call {@code find(selector).has()}.
+     *
+     * @param selector selector
+     * @return boolean
+     */
     boolean has(String selector);
-    
+
+    /**
+     * Returns true, if this element has any direct child matching predicate
+     *
+     * There is no method to make recursive check, but you can call {@code find(selector).has()}.
+     *
+     * @param selector selector
+     * @return boolean
+     */
     boolean has(Predicate<XMLContext> selector);
-    
+
+    /**
+     * Returns next sibling of element
+     * Returns null if there is no next sibling.
+     *
+     * @return XMLElement?
+     */
     XMLElement next();
-    
+
+    /**
+     * Returns all next siblings matched by provided selector.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements next(String selector);
-    
+
+    /**
+     * Returns all next siblings accepted by provided predicate.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements next(Predicate<XMLContext> selector);
-    
+
+    /**
+     * Returns previous sibling of element
+     * Returns null if there is no previous sibling.
+     *
+     * @return XMLElement?
+     */
     XMLElement prev();
-    
+
+    /**
+     * Returns all previous siblings matched by provided selector.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements prev(String selector);
-    
+
+    /**
+     * Returns all previous siblings accepted by provided predicate.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements prev(Predicate<XMLContext> selector);
-    
+
+    /**
+     * Returns direct parent of this element
+     * Returns null if there is no parent element.
+     *
+     * @return XMLElement?
+     */
     XMLElement parent();
-    
+
+    /**
+     * Returns parent chain for this element
+     *
+     * Elements are ordered from direct parent to root parent.
+     *
+     * @return XMLElements
+     */
     XMLElements parents();
-    
+
+    /**
+     * Returns those elements from parents chain which match selector.
+     *
+     * Elements are ordered from direct parent to root parent.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements parents(String selector);
-    
+
+    /**
+     * Returns those elements from parents chain which are accepted by predicate.
+     *
+     * Elements are ordered from direct parent to root parent.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements parents(Predicate<XMLContext> selector);
-    
+
+    /**
+     * Returns all siblings of element.
+     *
+     * @return XMLElements
+     */
     XMLElements siblings();
-    
+
+    /**
+     * Returns all siblings matched by provided selector.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements siblings(String selector);
-    
+
+    /**
+     * Returns all siblings accepted by provided predicate.
+     *
+     * @param selector selector
+     * @return XMLElements
+     */
     XMLElements siblings(Predicate<XMLContext> selector);
-    
-    
 
+
+    /**
+     * Normalization merges all text nodes and removes empty text nodes.
+     *
+     * @return this
+     */
     XMLElement normalize();
-    
+
+    /**
+     * Removes all child nodes.
+     *
+     * @return this
+     */
     XMLElement clear();
-    
+
+    /**
+     * Inserts provided element before this one. That means: "element" will be previous sibling.
+     *
+     * @param element element
+     * @return this
+     */
     XMLElement before(XMLElement element);
-    
+
+    /**
+     * Inserts provided element after this one. That means: "element" will be next sibling.
+     *
+     * @param element element
+     * @return this
+     */
     XMLElement after(XMLElement element);
-    
+
+    /**
+     * Inserts provided element into this one, before any children nodes. That means, as first child.
+     *
+     * @param element element
+     * @return this
+     */
     XMLElement prepend(XMLElement element);
-    
+
+    /**
+     * Inserts provided element into this one, after any children nodes. That means, as last child.
+     *
+     * @param element element
+     * @return this
+     */
     XMLElement append(XMLElement element);
-    
+
+    /**
+     * Replaces this element by provided one.
+     * That means: this element will be removed from document, and provided one will be inserted instead.
+     *
+     * Returns this element in detached state.
+     *
+     * @param element element
+     * @return this
+     */
     XMLElement replace(XMLElement element);
-    
+
+    /**
+     * Changes name of this element.
+     * Operation is supported only for attributes and tags.
+     *
+     * Throws exception if operation is unsupported.
+     *
+     * @param tagname tagname
+     * @return this
+     */
     XMLElement rename(String tagname);
-    
+
+    /**
+     * Removes this element from document.
+     *
+     * Returns this element in detached state.
+     *
+     * @return this
+     */
     XMLElement remove();
-    
+
+    /**
+     * Wraps this element by provided tag.
+     * That means: first it will be replaced by new "tagname" and then will be inserted into this "tagname"
+     *
+     * Returns newly created wrapper element.
+     *
+     * @param tagname tagname
+     * @return XMLElement
+     */
     XMLElement wrap(String tagname);
-    
+
+    /**
+     * Removes from document enclosing tag with all children and puts into its place only this element.
+     *
+     * @return this
+     */
     XMLElement unwrap();
-    
+
+    /**
+     * Changes content of this node.
+     *
+     * If this node is ELEMENT, it replaces its children by provided element.
+     * Otherwise, it reads text content from provided element and assigns it.
+     *
+     * @param value value
+     * @return this
+     */
     XMLElement content(XMLElement value);
-    
+
+    /**
+     * Changes content of this node.
+     *
+     * If this node is ELEMENT, parses provided markup into XML nodes and replaces current children by those new nodes.
+     * Otherwise, it just assigns provided text value to element.
+     *
+     * @param value value
+     * @return this
+     */
     XMLElement content(String value);
-    
+
+    /**
+     * Changes text content of this node.
+     *
+     * If this node is ELEMENT, it removes all children and puts new TEXT element into it.
+     * Otherwise, it just assigns provided text to element.
+     *
+     * @param value value
+     * @return this
+     */
     XMLElement text(String value);
-    
+
+    /**
+     * Executes provided transformer against document subtree represented by this element and
+     * creates new output document. Returns new tree generated by transformer
+     *
+     * @param transformer transformer
+     * @return XMLElement
+     * @throws XMLException on error
+     */
     XMLElement apply(Transformer transformer) throws XMLException;
-    
+
+    /**
+     * Executes provided transformer against document subtree represented by this element and
+     * creates new output document. Returns new tree generated by transformer
+     *
+     * Assumes that provided argument is correctly loaded XSLT document and uses it to create XML transformation.
+     *
+     * @param transformer transformer
+     * @return XMLElement
+     * @throws XMLException on error
+     */
     XMLElement apply(XMLElement transformer) throws XMLException;
-    
+
+    /**
+     * Executes provided transformer against document subtree represented by this element and
+     * stores generated result into "output" object.
+     *
+     * @param transformer transformer
+     * @param output output
+     * @param <R> R
+     * @return output
+     * @throws XMLException on error
+     */
     <R extends Result> R apply(Transformer transformer, R output) throws XMLException;
-    
+
+    /**
+     * Executes provided transformer against document subtree represented by this element and
+     * stores generated result into "output" object.
+     *
+     * Assumes that provided argument is correctly loaded XSLT document and uses it to create XML transformation.
+     *
+     * @param transformer transformer
+     * @param output output
+     * @param <R> R
+     * @return output
+     * @throws XMLException on error
+     */
     <R extends Result> R apply(XMLElement transformer, R output) throws XMLException;
-    
+
+    /**
+     * Creates new XMLWriter associated with this element.
+     * Writer allows you to configure XML generator and serialize this element.
+     *
+     * For example, you can enable pretty printing for returned writer.
+     *
+     * @return XMLWriter
+     */
     XMLWriter writer();
 
 }

+ 19 - 2
assira.core/src/main/java/net/ranides/assira/xml/XMLException.java

@@ -7,6 +7,7 @@
 package net.ranides.assira.xml;
 
 /**
+ * Unchecked exception thrown by XMLElement.
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
@@ -14,14 +15,30 @@ public class XMLException extends RuntimeException {
     
     private static final long serialVersionUID = 1L;
 
+    /**
+     * Constructs new XMLException
+     *
+     * @param cause cause
+     */
     public XMLException(Throwable cause) {
         super(cause);
     }
-    
+
+    /**
+     * Constructs new XMLException
+     *
+     * @param message message
+     */
     public XMLException(String message) {
         super(message);
     }
-    
+
+    /**
+     * Constructs new XMLException
+     *
+     * @param message message
+     * @param cause cause
+     */
     public XMLException(String message, Throwable cause) {
         super(message, cause);
     }

+ 47 - 2
assira.core/src/main/java/net/ranides/assira/xml/XMLSelector.java

@@ -12,6 +12,13 @@ import java.util.function.Predicate;
 import net.ranides.assira.xml.impl.W3Selectors;
 
 /**
+ * XMLSelector intenface can be used in two ways:
+ *  - to scan recursively provided context and find all matching elements
+ *  - to test provided context and tell if it matches criteria required by this selector
+ *
+ * In other words, can be used both as function or as predicate.
+ *
+ * There are few built-in selectors, for example CSS or XPATH.
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
@@ -23,16 +30,54 @@ public interface XMLSelector extends Function<XMLContext, XMLElements>, Predicat
     @Override
     boolean test(XMLContext context);
 
+    /**
+     * Factory: this method supports 3 types of selectors: CSS, XPATH and "byTagName"
+     * First, it detects type of selector.
+     *  - if you pass simple tag name, it will call {@link #name}.
+     *  - if you pass CSS expression, it will call {@link #css}
+     *  - if you pass XPATH prefixed by "? " text, it will call {@link #xpath}.
+     *
+     * To reiterate: XPATH expressions must be prefixed by "? "
+     *
+     * @param selector selector
+     * @return XMLSelector
+     */
     static XMLSelector compile(String selector) {
         return W3Selectors.compile(selector);
     }
-    
+
+    /**
+     * Creates new selector using CSS syntax.
+     *
+     * @param selector selector
+     * @return XMLSelector
+     */
     static XMLSelector css(String selector) {
         return W3Selectors.css(selector);
     }
-    
+
+    /**
+     * Creates new selector using XPATH syntax.
+     *
+     * Please note, that altough {@link #compile} requires "? " prefix, this method DOES NOT.
+     * Just pass ordinary correct XPATH expression.
+     *
+     * @param selector selector
+     * @return XMLSelector
+     */
     static XMLSelector xpath(String selector) {
         return W3Selectors.xpath(selector);
     }
+
+    /**
+     * Creates new selector which can be used to match direct children by tagname.
+     * Just pass ordinary tag name as argument.
+     *
+     * @param selector selector
+     * @return XMLSelector
+     */
+    static XMLSelector name(String selector) {
+        return W3Selectors.name(selector);
+    }
     
 }

+ 15 - 1
assira.core/src/main/java/net/ranides/assira/xml/XMLType.java

@@ -64,10 +64,24 @@ public enum XMLType implements Predicate<XMLContext> {
         this.value = value;
     }
 
+    /**
+     * Interoperability method: returns XMLType for provided "org.w3c.dom.Node"
+     *
+     * @param node node
+     * @return XMLType
+     */
     public static XMLType valueOf(Node node) {
         return valueOf(node.getNodeType());
     }
-    
+
+    /**
+     * Interoperability method: returns XMLType for provided NodeType (defined in "org.w3c.dom.Node")
+     *
+     * Returns null for invalid values.
+     *
+     * @param value value
+     * @return XMLType?
+     */
     public static XMLType valueOf(int value) {
         return MAP.apply(value);
     }

+ 55 - 4
assira.core/src/main/java/net/ranides/assira/xml/XMLWriter.java

@@ -13,24 +13,75 @@ import java.io.OutputStream;
 import java.io.Writer;
 
 /**
+ * XMLWriter is associated with some XMLElement and can be use to configure serialization options.
+ *
+ * Most of the time, writer is created using {@link XMLElement#writer()}.
+ * So you have to create XML document in memory first, and then you can create writer associated with them.
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
 public interface XMLWriter {
-    
+
+    /**
+     * Serializes associated document into provided file
+     *
+     * @param file file
+     * @return this
+     * @throws IOException on error
+     */
     XMLWriter save(File file) throws IOException;
 
+    /**
+     * Serializes associated document into provided stream
+     *
+     * @param ostream ostream
+     * @return this
+     * @throws IOException on error
+     */
     XMLWriter save(OutputStream ostream) throws IOException;
 
+    /**
+     * Serializes associated document into provided writer
+     *
+     * @param writer writer
+     * @return this
+     * @throws IOException on error
+     */
     XMLWriter save(Writer writer) throws IOException;
 
+    /**
+     * Serializes associated document and returns it as String
+     *
+     * @return String
+     */
     @Override
     String toString();
-    
+
+    /**
+     * Defines configuration property used by XML Parser generating output document.
+     *
+     * @param param param
+     * @param value value
+     * @return this
+     */
     XMLWriter param(XMLOptions param, String value);
-    
+
+    /**
+     * Defines configuration property used by XML Parser generating output document.
+     *
+     * @param param param
+     * @param value value
+     * @return this
+     */
     XMLWriter param(String param, String value);
-    
+
+    /**
+     * Enables pretty printing for this writer if provided size is greater than zero.
+     * Disables indentation otherwise.
+     *
+     * @param size size
+     * @return this
+     */
     XMLWriter indent(int size);
 
 }

+ 1 - 6
assira.core/src/main/java/net/ranides/assira/xml/impl/W3Element.java

@@ -24,11 +24,7 @@ import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.dom.DOMSource;
 
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
+import org.w3c.dom.*;
 
 import net.ranides.assira.collection.iterators.ForwardIterator;
 import net.ranides.assira.collection.query.CQuery;
@@ -36,7 +32,6 @@ import net.ranides.assira.generic.ValueUtils;
 import net.ranides.assira.reflection.IClass;
 import net.ranides.assira.text.StringUtils;
 import net.ranides.assira.xml.*;
-import org.w3c.dom.DOMException;
 
 /**
  * This is default implementation of XMLElement

+ 11 - 1
assira.core/src/main/java/net/ranides/assira/xml/impl/W3Selectors.java

@@ -47,11 +47,21 @@ public final class W3Selectors {
             return xpath(selector.substring(2));
         }
         if(isname(selector)) {
-            return new Name(selector);
+            return name(selector);
         }
         return css(selector);
     }
 
+    /**
+     * Internal method used by {@link XMLSelector#name(String)}
+     *
+     * @param selector selector
+     * @return XMLSelector
+     */
+    public static XMLSelector name(String selector) {
+        return new Name(selector);
+    }
+
     /**
      * Internal method used by {@link XMLSelector#css(String)}
      *

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/xml/impl/W3Writer.java

@@ -87,7 +87,7 @@ public class W3Writer implements XMLWriter {
             param(XMLOptions.INDENT, "no");
         } else {
             // we want to put "root tag" in new line after <?xml declaration?>
-            // DOCTYPE is workaround for strage bug in JDK formatter
+            // DOCTYPE is workaround for strange bug in JDK formatter
             param(XMLOptions.DOCTYPE_PUBLIC, ""); 
             param(XMLOptions.INDENT, "yes");
             param(XMLOptions.INDENT_AMOUNT, String.valueOf(size));