1 package org
.argeo
.cms
.dav
;
3 import java
.io
.IOException
;
4 import java
.io
.OutputStream
;
5 import java
.nio
.charset
.StandardCharsets
;
6 import java
.util
.HashSet
;
8 import java
.util
.concurrent
.ArrayBlockingQueue
;
9 import java
.util
.concurrent
.BlockingQueue
;
10 import java
.util
.concurrent
.CompletionStage
;
11 import java
.util
.concurrent
.TimeUnit
;
12 import java
.util
.concurrent
.atomic
.AtomicBoolean
;
13 import java
.util
.function
.Consumer
;
15 import javax
.xml
.XMLConstants
;
16 import javax
.xml
.namespace
.NamespaceContext
;
17 import javax
.xml
.namespace
.QName
;
18 import javax
.xml
.stream
.FactoryConfigurationError
;
19 import javax
.xml
.stream
.XMLOutputFactory
;
20 import javax
.xml
.stream
.XMLStreamException
;
21 import javax
.xml
.stream
.XMLStreamWriter
;
23 class MultiStatusWriter
implements Consumer
<DavResponse
> {
24 private BlockingQueue
<DavResponse
> queue
= new ArrayBlockingQueue
<>(64);
26 // private OutputStream out;
28 private Thread processingThread
;
30 private AtomicBoolean done
= new AtomicBoolean(false);
32 private AtomicBoolean polling
= new AtomicBoolean();
34 public void process(NamespaceContext namespaceContext
, OutputStream out
, CompletionStage
<Void
> published
,
35 boolean propname
) throws IOException
{
36 published
.thenRun(() -> allPublished());
37 processingThread
= Thread
.currentThread();
41 XMLOutputFactory xmlOutputFactory
= XMLOutputFactory
.newFactory();
42 XMLStreamWriter xsWriter
= xmlOutputFactory
.createXMLStreamWriter(out
, StandardCharsets
.UTF_8
.name());
43 xsWriter
.setNamespaceContext(namespaceContext
);
44 xsWriter
.setDefaultNamespace(DavXmlElement
.WEBDAV_NAMESPACE_URI
);
46 xsWriter
.writeStartDocument();
47 DavXmlElement
.multistatus
.startElement(xsWriter
);
48 xsWriter
.writeDefaultNamespace(DavXmlElement
.WEBDAV_NAMESPACE_URI
);
50 poll
: while (!(done
.get() && queue
.isEmpty())) {
51 DavResponse davResponse
;
54 davResponse
= queue
.poll(10, TimeUnit
.MILLISECONDS
);
55 if (davResponse
== null)
57 System
.err
.println(davResponse
.getHref());
58 } catch (InterruptedException e
) {
59 System
.err
.println(e
);
65 writeDavResponse(xsWriter
, davResponse
, propname
);
68 xsWriter
.writeEndElement();// multistatus
69 xsWriter
.writeEndDocument();
72 } catch (FactoryConfigurationError
| XMLStreamException e
) {
74 processingThread
= null;
79 protected void writeDavResponse(XMLStreamWriter xsWriter
, DavResponse davResponse
, boolean propname
)
80 throws XMLStreamException
{
81 Set
<String
> namespaces
= new HashSet
<>();
82 for (QName key
: davResponse
.getPropertyNames()) {
83 if (key
.getNamespaceURI().equals(DavXmlElement
.WEBDAV_NAMESPACE_URI
))
85 if (key
.getNamespaceURI().equals(XMLConstants
.W3C_XML_SCHEMA_NS_URI
))
87 namespaces
.add(key
.getNamespaceURI());
89 DavXmlElement
.response
.startElement(xsWriter
);
91 for (String ns
: namespaces
)
92 xsWriter
.writeNamespace(xsWriter
.getNamespaceContext().getPrefix(ns
), ns
);
94 DavXmlElement
.href
.setSimpleValue(xsWriter
, davResponse
.getHref());
97 DavXmlElement
.propstat
.startElement(xsWriter
);
99 DavXmlElement
.prop
.startElement(xsWriter
);
100 if (!davResponse
.getResourceTypes().isEmpty() || davResponse
.isCollection()) {
101 DavXmlElement
.resourcetype
.startElement(xsWriter
);
102 if (davResponse
.isCollection())
103 DavXmlElement
.collection
.emptyElement(xsWriter
);
104 for (QName resourceType
: davResponse
.getResourceTypes()) {
105 xsWriter
.writeEmptyElement(resourceType
.getNamespaceURI(), resourceType
.getLocalPart());
107 xsWriter
.writeEndElement();// resource type
109 for (QName key
: davResponse
.getPropertyNames()) {
111 xsWriter
.writeEmptyElement(key
.getNamespaceURI(), key
.getLocalPart());
113 xsWriter
.writeStartElement(key
.getNamespaceURI(), key
.getLocalPart());
114 xsWriter
.writeCData(davResponse
.getProperties().get(key
));
115 xsWriter
.writeEndElement();
118 xsWriter
.writeEndElement();// prop
120 xsWriter
.writeEndElement();// propstat
122 xsWriter
.writeEndElement();// response
126 public void accept(DavResponse davResponse
) {
128 queue
.put(davResponse
);
129 } catch (InterruptedException e
) {
134 protected synchronized void allPublished() {
136 if (processingThread
!= null && queue
.isEmpty() && polling
.get()) {
137 // we only interrupt if the queue is already processed
138 // so as not to interrupt I/O
139 processingThread
.interrupt();