Package com.bradmcevoy.http.webdav

Source Code of com.bradmcevoy.http.webdav.PropFindXmlGenerator

package com.bradmcevoy.http.webdav;

import com.bradmcevoy.http.Response;
import com.bradmcevoy.http.Response.Status;
import com.bradmcevoy.http.XmlWriter;
import com.bradmcevoy.http.values.ValueAndType;
import com.bradmcevoy.http.values.ValueWriters;
import com.bradmcevoy.http.webdav.PropFindResponse.NameAndError;
import org.apache.commons.io.output.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author brad
*/
public class PropFindXmlGenerator {

    private static final Logger log = LoggerFactory.getLogger( PropFindXmlGenerator.class );
    private final Helper helper;
    private final ValueWriters valueWriters;

    public PropFindXmlGenerator( ValueWriters valueWriters ) {
        helper = new Helper();
        this.valueWriters = valueWriters;
    }

    PropFindXmlGenerator( Helper helper, ValueWriters valueWriters ) {
        this.helper = helper;
        this.valueWriters = valueWriters;
    }

    public String generate( List<PropFindResponse> propFindResponses ) {
        ByteArrayOutputStream responseOutput = new ByteArrayOutputStream();
        Map<String, String> mapOfNamespaces = helper.findNameSpaces( propFindResponses );
        ByteArrayOutputStream generatedXml = new ByteArrayOutputStream();
        XmlWriter writer = new XmlWriter( generatedXml );
        writer.writeXMLHeader();
        writer.open(WebDavProtocol.NS_DAV.getPrefix() ,"multistatus" + helper.generateNamespaceDeclarations( mapOfNamespaces ) );
        writer.newLine();
        helper.appendResponses( writer, propFindResponses, mapOfNamespaces );
        writer.close(WebDavProtocol.NS_DAV.getPrefix(),"multistatus" );
        writer.flush();
//        log.debug( generatedXml.toString() );
        helper.write( generatedXml, responseOutput );
        try {
            return responseOutput.toString( "UTF-8" );
        } catch( UnsupportedEncodingException ex ) {
            throw new RuntimeException( ex );
        }
    }

    class Helper {

        /**
         *
         * @param propFindResponses
         * @return - map where key is the uri, and value is the prefix
         */
        Map<String, String> findNameSpaces( List<PropFindResponse> propFindResponses ) {
            int i = 1;
            Map<String, String> map = new HashMap<String, String>();
           
            // always add webdav namespace
            map.put( WebDavProtocol.NS_DAV.getName(), WebDavProtocol.NS_DAV.getPrefix() );

            for( PropFindResponse r : propFindResponses ) {
                for( QName p : r.getKnownProperties().keySet() ) {
                    String uri = p.getNamespaceURI();
//                    if( uri.endsWith( ":" ) ) uri = uri.substring( 0, uri.length() - 1 ); // strip trailing :
                    if( !map.containsKey( uri ) ) {
                        map.put( uri, "ns" + i++ );
                    }
                }
            }
            return map;
        }

        String generateNamespaceDeclarations( Map<String, String> mapOfNamespaces ) {
            String decs = "";
            for( String uri : mapOfNamespaces.keySet() ) {
                String prefix = mapOfNamespaces.get( uri );
                decs += " xmlns:" + prefix + "=\"" + uri + "\"";
            }
            return decs;
        }

        void appendResponses( XmlWriter writer, List<PropFindResponse> propFindResponses, Map<String, String> mapOfNamespaces ) {
//            log.debug( "appendResponses: " + propFindResponses.size() );
            for( PropFindResponse r : propFindResponses ) {
                XmlWriter.Element el = writer.begin(WebDavProtocol.NS_DAV.getPrefix(), "response" );
                el.open();
                writer.writeProperty( WebDavProtocol.NS_DAV.getPrefix(), "href", r.getHref() );
                sendKnownProperties( writer, mapOfNamespaces, r.getKnownProperties(), r.getHref() );
                if( r.getErrorProperties() != null ) {
                    for( Status status : r.getErrorProperties().keySet()) {
                        List<NameAndError> props = r.getErrorProperties().get(status);
                        sendErrorProperties( status, writer, mapOfNamespaces, props );
                    }
                }
                el.close();
            }
        }

        private void sendKnownProperties( XmlWriter writer, Map<String, String> mapOfNamespaces, Map<QName, ValueAndType> properties, String href ) {
            sendProperties(Response.Status.SC_OK, writer, mapOfNamespaces, properties, href);
        }

        private void sendProperties( Response.Status status, XmlWriter writer, Map<String, String> mapOfNamespaces, Map<QName, ValueAndType> properties, String href ) {
            if( !properties.isEmpty() ) {
                XmlWriter.Element elPropStat = writer.begin(WebDavProtocol.NS_DAV.getPrefix(), "propstat" ).open();
                XmlWriter.Element elProp = writer.begin(WebDavProtocol.NS_DAV.getPrefix(), "prop" ).open();
                for( QName qname : properties.keySet() ) {
                    String prefix = mapOfNamespaces.get( qname.getNamespaceURI() );
                    ValueAndType val = properties.get( qname );
                    valueWriters.writeValue( writer, qname, prefix, val, href, mapOfNamespaces );
                }
                elProp.close();
                writer.writeProperty( WebDavProtocol.NS_DAV.getPrefix(), "status", status.toString() );
                elPropStat.close();
            }
        }

        private void sendErrorProperties( Response.Status status, XmlWriter writer, Map<String, String> mapOfNamespaces, List<NameAndError> properties ) {
//            log.debug( "sendUnknownProperties: " + properties.size() );
            if( !properties.isEmpty() ) {
                XmlWriter.Element elPropStat = writer.begin(WebDavProtocol.NS_DAV.getPrefix(), "propstat" ).open();
                XmlWriter.Element elProp = writer.begin(WebDavProtocol.NS_DAV.getPrefix(), "prop" ).open();
                for( NameAndError ne : properties ) {
                    QName qname = ne.getName();
                    String prefix = mapOfNamespaces.get( qname.getNamespaceURI() );
                    writer.writeProperty( prefix, qname.getLocalPart() );
                }
                elProp.close();
                writer.writeProperty( WebDavProtocol.NS_DAV.getPrefix(), "status", status.toString() );
                elPropStat.close();
            }
        }

        void write( ByteArrayOutputStream out, OutputStream outputStream ) {
            try {
                String xml = out.toString( "UTF-8" );
                outputStream.write( xml.getBytes() ); // note: this can and should write to the outputstream directory. but if it aint broke, dont fix it...
            } catch( UnsupportedEncodingException ex ) {
                throw new RuntimeException( ex );
            } catch( IOException ex ) {
                throw new RuntimeException( ex );
            }
        }
    }
}
TOP

Related Classes of com.bradmcevoy.http.webdav.PropFindXmlGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.