1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_webdav.hxx"
24 
25 #include <rtl/ustrbuf.hxx>
26 #include "DAVProperties.hxx"
27 #include "ProppatchRequest.hxx"
28 #include "UCBDeadPropertyValue.hxx"
29 
30 using namespace http_dav_ucp;
31 
32 #define PROPPATCH_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propertyupdate xmlns=\"DAV:\">"
33 #define PROPPATCH_TRAILER "</propertyupdate>"
34 
generatePROPPATCHRequestBody(const std::vector<ProppatchValue> & inProperties)35 rtl::OString ProppatchRequest::generatePROPPATCHRequestBody(
36             const std::vector< ProppatchValue > & inProperties )
37 {
38     rtl::OString aBodyText;
39     static const struct
40     {
41         const char *str;
42         sal_Int32   len;
43     }
44     OpCode [] = {
45         { RTL_CONSTASCII_STRINGPARAM( "set" ) },
46         { RTL_CONSTASCII_STRINGPARAM( "remove" ) }
47     };
48     if ( inProperties.size() > 0 )
49     {
50         rtl::OUStringBuffer aBuffer;
51         // add PropPatch xml header in front
52         aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( PROPPATCH_HEADER ));
53 
54         // <*operation code*><prop>
55 
56         ProppatchOperation lastOp = inProperties[ 0 ].operation;
57         aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<" ));
58         aBuffer.appendAscii( OpCode[lastOp].str, OpCode[lastOp].len );
59         aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "><prop>" ));
60 
61         CurlPropName thePropName;
62         for ( unsigned long n = 0; n < inProperties.size(); ++n )
63         {
64             const ProppatchValue & rProperty = inProperties[ n ];
65             // split fullname into namespace and name!
66             DAVProperties::createCurlPropName( rProperty.name,
67                                                thePropName );
68 
69             if ( rProperty.operation != lastOp )
70             {
71                 // </prop></*last operation code*><*operation code><prop>
72                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "</prop></" ));
73                 aBuffer.appendAscii( OpCode[lastOp].str, OpCode[lastOp].len );
74                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "><" ));
75                 aBuffer.appendAscii( OpCode[rProperty.operation].str, OpCode[rProperty.operation].len );
76                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "><prop>" ));
77             }
78 
79             // <*propname* xmlns="*propns*"
80             aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<" ));
81             aBuffer.appendAscii( thePropName.name );
82             aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " xmlns=\"" ));
83             aBuffer.appendAscii( thePropName.nspace );
84             aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ));
85 
86             if ( rProperty.operation == PROPSET )
87             {
88                 // >*property value*</*propname*>
89                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( ">" ));
90 
91                 rtl::OUString aStringValue;
92                 if ( DAVProperties::isUCBDeadProperty( thePropName ) )
93                 {
94                     UCBDeadPropertyValue::toXML( rProperty.value,
95                                                  aStringValue );
96                 }
97                 else
98                 {
99                     rProperty.value >>= aStringValue;
100                 }
101                 aBuffer.append( aStringValue );
102                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "</" ));
103                 aBuffer.appendAscii( thePropName.name );
104                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( ">" ));
105             }
106             else
107             {
108                 // />
109                 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/>" ));
110             }
111 
112             lastOp = rProperty.operation;
113         }
114 
115         // </prop></*last operation code*>
116         aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "</prop></" ));
117         aBuffer.appendAscii( OpCode[lastOp].str, OpCode[lastOp].len );
118         aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( ">" ));
119 
120         // add PropPatch xml trailer at end
121         aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( PROPPATCH_TRAILER ));
122 
123         return rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
124     }
125     return rtl::OString();
126 }
127