/******************************************************************************* * Copyright (c) 2004, 2008 John Krasnay and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * John Krasnay - initial API and implementation *******************************************************************************/ package net.sf.vex.dom; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * Represents a fragment of an XML document. */ public class DocumentFragment implements Serializable { /** * Mime type representing document fragments: * "text/x-vex-document-fragment" */ public static final String MIME_TYPE = "application/x-vex-document-fragment"; private Content content; private Element[] elements; /** * Class constructor. * * @param content Content holding the fragment's content. * @param elements Elements that make up this fragment. */ public DocumentFragment(Content content, Element[] elements) { this.content = content; this.elements = elements; } /** * Returns the Content object holding this fragment's content. */ public Content getContent() { return this.content; } /** * Returns the number of characters, including sentinels, represented * by the fragment. */ public int getLength() { return this.content.getLength(); } /** * Returns the elements that make up this fragment. */ public Element[] getElements() { return this.elements; } /** * Returns an array of element names and Validator.PCDATA representing * the content of the fragment. */ public String[] getNodeNames() { Node[] nodes = this.getNodes(); String[] names = new String[nodes.length]; for (int i = 0; i < nodes.length; i++) { if (nodes[i] instanceof Text) { names[i] = Validator.PCDATA; } else { names[i] = ((Element) nodes[i]).getName(); } } return names; } /** * Returns the nodes that make up this fragment, including * elements and <code>Text</code> objects. */ public Node[] getNodes() { return Document.createNodeArray( this.getContent(), 0, this.getContent().getLength(), this.getElements()); } //======================================================= PRIVATE /* * Custom Serialization Methods */ private void writeObject(ObjectOutputStream out) throws IOException { out.writeUTF(this.content.getString(0, this.content.getLength())); out.writeInt(this.elements.length); for (int i = 0; i < this.elements.length; i++) { this.writeElement(this.elements[i], out); } } private void writeElement(Element element, ObjectOutputStream out) throws IOException { out.writeObject(element.getName()); out.writeInt(element.getStartOffset()); out.writeInt(element.getEndOffset()); String[] attrNames = element.getAttributeNames(); out.writeInt(attrNames.length); for (int i = 0; i < attrNames.length; i++) { out.writeObject(attrNames[i]); out.writeObject(element.getAttribute(attrNames[i])); } Element[] children = element.getChildElements(); out.writeInt(children.length); for (int i = 0; i < children.length; i++) { this.writeElement(children[i], out); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { String s = in.readUTF(); this.content = new GapContent(s.length()); content.insertString(0, s); int n = in.readInt(); this.elements = new Element[n]; for (int i = 0; i < n; i++) { this.elements[i] = this.readElement(in); } } private Element readElement(ObjectInputStream in) throws IOException, ClassNotFoundException { String name = (String) in.readObject(); int startOffset = in.readInt(); int endOffset = in.readInt(); Element element = new Element(name); element.setContent(this.content, startOffset, endOffset); int attrCount = in.readInt(); for (int i = 0; i < attrCount; i++) { String key = (String) in.readObject(); String value = (String) in.readObject(); try { element.setAttribute(key, value); } catch (DocumentValidationException e) { // Should never happen; there ain't no document e.printStackTrace(); } } int childCount = in.readInt(); for (int i = 0; i < childCount; i++) { Element child = this.readElement(in); child.setParent(element); element.insertChild(i, child); } return element; } }