📄 documentimpl.java
字号:
/** * Return true if certain feature for specific DOM version supported by this * implementation. * * @param feature Name of feature to check * @param version Optional version number * @return True if supported */ public boolean hasFeature( String feature, String version ) { // Versions higher than 1.0 not supported yet. if (version != null) { if (version.indexOf( "1.0" ) < 0 && version.indexOf( "Level 1" ) < 0) { return false; } } // Supports XML and HTML. if (feature != null) { if (feature.equalsIgnoreCase( "XML" ) || feature.equalsIgnoreCase( "HTML" )) { return true; } } return false; } /** * Register an application-defined element type. The element's tag name and * class are specified. When a so named element is created with {@link * #createElement}, an object of the specified class is created and returned. * This allows applications to define classes for specific element types. * * @param tagName The name of the element tag * @param elementClass Class derived from {@link org.openxml.XMLElement}, * used to construct the element */ public void registerElement( String tagName, Class elementClass ) { if (tagName == null || tagName.length() == 0) { throw new NullPointerException( "Argument 'tagName' is null or an empty string." ); } if (elementClass == null || elementClass.isAssignableFrom( Element.class )) { throw new IllegalArgumentException( "Argument 'elementClass' is null or does not extend Element." ); } if (_elementTypes == null) { _elementTypes = new Hashtable(); } _elementTypes.put( tagName, elementClass ); } public void assignDoctype( DocumentTypeProxy docType ) { if (docType == null) { throw new NullPointerException( "Argument 'docType' is null." ); } if (_docType != null) { throw new IllegalStateException( "Document type already assigned to this document." ); } _docType = docType; } /** * Implements a lock mechanism. The lock mechanism differs from synchronization * in that it supports multiple function calls, while still preserving the lock * granted to a specific thread. Caution is required as other threads may obtain * access without first acquiring lock. All implementations of the lock mechanism * should use {@link #lock}, {@link #unlock} and {@link #acquire} to assure true * synchronization. * <P> * Calling {@link #lock} obtains a lock to the current running thread. If the * lock has already been granted to some other thread, this call will block * until the lock is released or until the lock has timed out. * <P> * Calling {@link #unlock} releases the lock from the current thread, if still * held by the current thread. A thread may call {@link #lock} any number of * times and must call {@link #unlock} that number of times to release the * lock. The thread may call {@link #unlock} an additional number of times if * necessary by the implementation. * <P> * If a thread requires access to a resource that might be lock, it should * acquire it by calling {@link #acquire}. This method will block until the * resource is unlocked by some other thread. If the resource is unlocked, * or locked by the current thread, {@link #acquire} will return immediately. */ /** * Obtains a lock, preventing other threads from gaining access to the locked * resource. The lock is retained across multiple calls, until {@link #unlock} * is called. Attempts to call {@link #acquire} from another thread will be * blocked. * <P> * If the resource is already locked by another thread, the method will * block until the lock is released or until the block has timedout. * <P> * {@link #lock} may be called any number of times, and {@link #unlock} must * be called that number of times to release the lock. * * @see #unlock */ public void lock() throws RuntimeException { synchronized (this) { // If current thread is locking, increase the lock count. // Otherwise, wait for lock to be released, acquire the lock and // increase the lock count. If timeout has reached or thread has // been interrupted, acquire() will throw an exception. if (_lockThread == Thread.currentThread()) { ++_lockCount; } else { acquire( Long.MAX_VALUE ); _lockThread = Thread.currentThread(); ++_lockCount; } } } /** * Releases a lock, so other thread may gain access to the resource. {@link * #unlock} must be called as many times as {@link #lock} was called to * release the lock. {@link #unlock} may be called an additional number of * times, if so required by the implementation (e.g. to assure that a lock * is released at the end of a thread). * * @see #lock */ public void unlock() { // If the current thread is locking, decrease the lock count. // If the lock count is zero, release the lock, otherwise unlock() // must be called again to release lock. if (_lockThread == Thread.currentThread()) { synchronized (this) { --_lockCount; if (_lockCount == 0) { _lockThread = null; notify(); } } } } /** * Called to acquire access to a possible locked resource. If the resource * was locked by the current thread, the method will return immediately. * If the resource was locked by some other thread, the method will block * until the resource is unlocked, or the block has timed out. * * @see #lock * @see #unlock */ public void acquire( long lockTimeout ) throws RuntimeException { long start; long timeout; synchronized (this) { try { // If the application is not locked by the current thread, // wait until the application is unlocked, then proceed. if (_lockThread != Thread.currentThread() && _lockThread != null) { // Remember when started waiting for lock to implement // timeout. Repeat until lock is released by other thread, // or until timeout has expired. start = System.currentTimeMillis(); while (_lockThread != null && lockTimeout > (System.currentTimeMillis() - start)) { // If the locking thread is dead, release the lock // immediately, otherwise, wait for it to be released. if (!_lockThread.isAlive()) { _lockThread = null; } else { wait( lockTimeout - System.currentTimeMillis() - start ); } } // Timeout, throw an exception. if (_lockThread != null) { throw new RuntimeException( "Timeout waiting for lock to be released." ); } } } catch (InterruptedException except) { // Thread interrupted, throw an exception. throw new RuntimeException( "Timeout waiting for lock to be released." ); } } } public synchronized boolean equals( Object other ) { DocumentProxy otherX; // Use Node's equals method to perform the first tests of equality. // If these tests do not pass, return false. if (!super.equals( other )) { return false; } // Very simple equality test: are the document types equal. // There's nothing else about the document to compare. synchronized (other) { otherX = (DocumentProxy)other; return getDoctype() == null && otherX.getDoctype() == null || getDoctype() != null && otherX.getDoctype() != null && _docType.equals( otherX.getDoctype() ); } } public Object clone() { DocumentProxy clone = null; try { clone = (DocumentProxy)database().createObject( DocumentImpl.class.getName() ); cloneInto( (NodeProxy)clone, true ); } catch (Exception except) { throw new DOMExceptionImpl( DOMExceptionImpl.PDOM_ERR, except.getMessage() ); } return clone; } public Node cloneNode( boolean deep ) { DocumentProxy clone = null; try { clone = (DocumentProxy)database().createObject( DocumentImpl.class.getName() ); cloneInto( (NodeProxy)clone, deep ); } catch (Exception except) { throw new DOMExceptionImpl( DOMExceptionImpl.PDOM_ERR, except.getMessage() ); } return clone; } public String toString() { return "Document: "; } public synchronized void cloneInto( NodeProxy into, boolean deep ) { DocumentTypeProxy docType; // Use the Node cloning method. The DOM object does not need cloning, // but the document type (which contains entities, notations, etc) // must be cloned. super.cloneInto( into, deep ); if (deep) { if (_docType != null) { ((DocumentProxy)into).setDoctype( (DocumentTypeProxy)_docType.clone() ); } // If application elements are defined, clone the list as well. if (_elementTypes != null) { ((DocumentProxy)into).setElementTypes( (Hashtable)_elementTypes.clone() ); } } else { ((DocumentProxy)into).setDoctype( _docType ); ((DocumentProxy)into).setElementTypes( _elementTypes ); } // ((DocumentProxy)into).setElementFactory (_elementFactory); } protected final boolean supportsChildern() { return true; } public DocumentImpl() { super( null, "#document", null, false ); _ownerDocument = this; } protected DocumentImpl( String rootElement ) { super( null, rootElement != null ? rootElement : "", null, rootElement != null ); _ownerDocument = this; } public void onDelete() throws Exception { if (_docType != null) { database().deleteObject( _docType ); } Node node = getFirstChild(); while (node != null) { deleteAllChildern( node ); node = getNextSibling(); } } private void deleteAllChildern( Node node ) throws Exception { Node dummyNode; while (node != null) { if (node.hasChildNodes()) { deleteAllChildern( node.getFirstChild() ); } dummyNode = node.getNextSibling(); database().deleteObject( (OzoneRemote)node ); node = dummyNode; } } /** * The document type definition of this document (per DOM API). Only available * if document was created with a DTD and not available for HTML documents. */ private DocumentTypeProxy _docType; /** * Holds a reference to the locking thread. When unlocked, this reference is * null. This object is used both to designate a lock, identify the locking * thread, and perform a {@link Object#wait}. * * @see #lock * @see #unlock */ private Thread _lockThread; /** * Implement counting on locks, allowing {@link #lock} to be called a * multiple number of times, and {@link #unlock} to still retain the lock * on the outer calls. * * @see #lock * @see #unlock */ private int _lockCount; /** * Holds names and classes of application element types. When an element * with a particular tag name is created, the matching {@link java.lang.Class} * is used to create the element object. This reference is null unless an * element has been defined. */ private Hashtable _elementTypes;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -