public boolean write()

in src/org/apache/xml/serializer/dom3/LSSerializerImpl.java [887:1097]


    public boolean write(Node nodeArg, LSOutput destination) throws LSException {
        // If the destination is null
        if (destination == null) {
            String msg = Utils.messages
            .createMessage(
                    MsgKey.ER_NO_OUTPUT_SPECIFIED,
                    null);
            if (fDOMErrorHandler != null) {
                fDOMErrorHandler.handleError(new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR, msg,
                        MsgKey.ER_NO_OUTPUT_SPECIFIED));
            }
            throw new LSException(LSException.SERIALIZE_ERR, msg);
        } 
        
        // If nodeArg is null, return false.  Should we throw and LSException instead?
        if (nodeArg == null ) {
            return false;
        }

        // Obtain a reference to the serializer to use
        // Serializer serializer = getXMLSerializer(xmlVersion);
        Serializer serializer = fXMLSerializer;
        serializer.reset();
        
        // If the node has not been seen
        if ( nodeArg != fVisitedNode) {
            // Determine the XML Document version of the Node 
            String xmlVersion = getXMLVersion(nodeArg);
            
            // Determine the encoding: 1.LSOutput.encoding, 2.Document.inputEncoding, 3.Document.xmlEncoding. 
            fEncoding = destination.getEncoding();
            if (fEncoding == null ) {
            	fEncoding = getInputEncoding(nodeArg);
            	fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg);
            }

            // If the encoding is not recognized throw an exception.
            // Note: The serializer defaults to UTF-8 when created
            if (!Encodings.isRecognizedEncoding(fEncoding)) {
                String msg = Utils.messages
                .createMessage(
                        MsgKey.ER_UNSUPPORTED_ENCODING,
                        null);
                if (fDOMErrorHandler != null) {
                    fDOMErrorHandler.handleError(new DOMErrorImpl(
                            DOMError.SEVERITY_FATAL_ERROR, msg,
                            MsgKey.ER_UNSUPPORTED_ENCODING));
                }
                throw new LSException(LSException.SERIALIZE_ERR, msg);            	
            }
            
            serializer.getOutputFormat().setProperty("version", xmlVersion);

            // Set the output encoding and xml version properties
            fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
            fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding);
            
            // If the node to be serialized is not a Document, Element, or Entity
            // node
            // then the XML declaration, or text declaration, should be never be
            // serialized.
            if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE
                    || nodeArg.getNodeType() != Node.ELEMENT_NODE
                    || nodeArg.getNodeType() != Node.ENTITY_NODE)
                    && ((fFeatures & XMLDECL) != 0)) {
                fDOMConfigProperties.setProperty(
                        DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
                        DOMConstants.DOM3_DEFAULT_FALSE);
            }

            fVisitedNode = nodeArg;
        } 
        
        // Update the serializer properties
        fXMLSerializer.setOutputFormat(fDOMConfigProperties);
        
        // 
        try {
            
            // The LSSerializer will use the LSOutput object to determine 
            // where to serialize the output to in the following order the  
            // first one that is not null and not an empty string will be    
            // used: 1.LSOutput.characterStream, 2.LSOutput.byteStream,   
            // 3. LSOutput.systemId 
            // 1.LSOutput.characterStream
            Writer writer = destination.getCharacterStream();
            if (writer == null ) {
                
                // 2.LSOutput.byteStream
                OutputStream outputStream = destination.getByteStream();
                if ( outputStream == null) {
                    
                    // 3. LSOutput.systemId
                    String uri = destination.getSystemId();
                    if (uri == null) {
                        String msg = Utils.messages
                        .createMessage(
                                MsgKey.ER_NO_OUTPUT_SPECIFIED,
                                null);
                        if (fDOMErrorHandler != null) {
                            fDOMErrorHandler.handleError(new DOMErrorImpl(
                                    DOMError.SEVERITY_FATAL_ERROR, msg,
                                    MsgKey.ER_NO_OUTPUT_SPECIFIED));
                        }
                        throw new LSException(LSException.SERIALIZE_ERR, msg);
                        
                    } else {
                        // Expand the System Id and obtain an absolute URI for it.
                        String absoluteURI = SystemIDResolver.getAbsoluteURI(uri);
                        
                        URL url = new URL(absoluteURI);
                        OutputStream urlOutStream = null;
                        String protocol = url.getProtocol();
                        String host = url.getHost();
                        
                        // For file protocols, there is no need to use a URL to get its
                        // corresponding OutputStream
                        
                        // Scheme names consist of a sequence of characters. The lower case
                        // letters "a"--"z", digits, and the characters plus ("+"), period
                        // ("."), and hyphen ("-") are allowed. For resiliency, programs
                        // interpreting URLs should treat upper case letters as equivalent to
                        // lower case in scheme names (e.g., allow "HTTP" as well as "http").
                        if (protocol.equalsIgnoreCase("file") 
                                && (host == null || host.length() == 0 || host.equals("localhost"))) {
                            // do we also need to check for host.equals(hostname)
                            urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath()));
                           
                        } else {
                            // This should support URL's whose schemes are mentioned in 
                            // RFC1738 other than file
                            
                            URLConnection urlCon = url.openConnection();
                            urlCon.setDoInput(false);
                            urlCon.setDoOutput(true);
                            urlCon.setUseCaches(false); 
                            urlCon.setAllowUserInteraction(false);
                            
                            // When writing to a HTTP URI, a HTTP PUT is performed.
                            if (urlCon instanceof HttpURLConnection) {
                                HttpURLConnection httpCon = (HttpURLConnection) urlCon;
                                httpCon.setRequestMethod("PUT");
                            }
                            urlOutStream = urlCon.getOutputStream();
                        }
                        // set the OutputStream to that obtained from the systemId
                        serializer.setOutputStream(urlOutStream);
                    }
                } else {
                    // 2.LSOutput.byteStream
                    serializer.setOutputStream(outputStream);     
                }
            } else {
                // 1.LSOutput.characterStream
                serializer.setWriter(writer);
            }
            
            // The associated media type by default is set to text/xml on 
            // org.apache.xml.serializer.SerializerBase.  
            
            // Get a reference to the serializer then lets you serilize a DOM
            // Use this hack till Xalan support JAXP1.3
            if (fDOMSerializer == null) {
               fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
            } 
            
            // Set the error handler on the DOM3Serializer interface implementation
            if (fDOMErrorHandler != null) {
                fDOMSerializer.setErrorHandler(fDOMErrorHandler);
            }
            
            // Set the filter on the DOM3Serializer interface implementation
            if (fSerializerFilter != null) {
                fDOMSerializer.setNodeFilter(fSerializerFilter);
            }
            
            // Set the NewLine character to be used
            fDOMSerializer.setNewLine(fEndOfLine.toCharArray());
            
            // Serializer your DOM, where node is an org.w3c.dom.Node
            // Assuming that Xalan's serializer can serialize any type of DOM node
            fDOMSerializer.serializeDOM3(nodeArg);
            
        } catch( UnsupportedEncodingException ue) {
            
            String msg = Utils.messages
            .createMessage(
                    MsgKey.ER_UNSUPPORTED_ENCODING,
                    null);
            if (fDOMErrorHandler != null) {
                fDOMErrorHandler.handleError(new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR, msg,
                        MsgKey.ER_UNSUPPORTED_ENCODING, ue));
            }
            throw (LSException) createLSException(LSException.SERIALIZE_ERR, ue).fillInStackTrace();
        } catch (LSException lse) {
            // Rethrow LSException.
            throw lse;
        } catch (RuntimeException e) {
            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
        }  catch (Exception e) {
            if (fDOMErrorHandler != null) {
                fDOMErrorHandler.handleError(new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
                        null, e));
            }
            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
        }        
        return true;
    }