xref: /AOO41X/main/ucb/source/ucp/webdav/SerfPropPatchReqProcImpl.cxx (revision c966c2767fb7824758cc9ea4cc4af5e395cd580d)
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_ucb.hxx"
24 
25 #include <rtl/ustring.hxx>
26 #include <DAVProperties.hxx>
27 #include <UCBDeadPropertyValue.hxx>
28 
29 #include <SerfPropPatchReqProcImpl.hxx>
30 #include <SerfTypes.hxx>
31 
32 namespace http_dav_ucp
33 {
34 
35 SerfPropPatchReqProcImpl::SerfPropPatchReqProcImpl( const char* inPath,
36                                                     const DAVRequestHeaders& inRequestHeaders,
37                                                     const std::vector< ProppatchValue > & inProperties )
38     : SerfRequestProcessorImpl( inPath, inRequestHeaders )
39     , mpProperties( &inProperties )
40 {
41 }
42 
43 SerfPropPatchReqProcImpl::~SerfPropPatchReqProcImpl()
44 {
45 }
46 
47 #define PROPPATCH_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propertyupdate xmlns=\"DAV:\">"
48 #define PROPPATCH_TRAILER "</propertyupdate>"
49 
50 serf_bucket_t * SerfPropPatchReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest )
51 {
52     serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest );
53 
54     // body bucket
55     serf_bucket_t* body_bkt = 0;
56     rtl::OUString aBodyText;
57     {
58         // create and fill body bucket with properties to be set or removed
59         static const char* OpCodes[2] = { "set", "remove" };
60         const int nPropCount = ( mpProperties != 0 )
61                                ? mpProperties->size()
62                                : 0;
63         if ( nPropCount > 0 )
64         {
65             // <*operation code*><prop>
66             ProppatchOperation lastOp = (*mpProperties)[ 0 ].operation;
67             aBodyText += rtl::OUString::createFromAscii( "<" );
68             aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] );
69             aBodyText += rtl::OUString::createFromAscii( "><prop>" );
70 
71             SerfPropName thePropName;
72             for ( int n = 0; n < nPropCount; ++n )
73             {
74                 const ProppatchValue & rProperty = (*mpProperties)[ n ];
75                 // split fullname into namespace and name!
76                 DAVProperties::createSerfPropName( rProperty.name,
77                                                    thePropName );
78 
79                 if ( rProperty.operation != lastOp )
80                 {
81                     // </prop></*last operation code*><*operation code><prop>
82                     aBodyText += rtl::OUString::createFromAscii( "</prop></" );
83                     aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] );
84                     aBodyText += rtl::OUString::createFromAscii( "><" );
85                     aBodyText += rtl::OUString::createFromAscii( OpCodes[rProperty.operation] );
86                     aBodyText += rtl::OUString::createFromAscii( "><prop>" );
87                 }
88 
89                 // <*propname* xmlns="*propns*"
90                 aBodyText += rtl::OUString::createFromAscii( "<" );
91                 aBodyText += rtl::OUString::createFromAscii( thePropName.name );
92                 aBodyText += rtl::OUString::createFromAscii( " xmlns=\"" );
93                 aBodyText += rtl::OUString::createFromAscii( thePropName.nspace );
94                 aBodyText += rtl::OUString::createFromAscii( "\"" );
95 
96                 if ( rProperty.operation == PROPSET )
97                 {
98                     // >*property value*</*propname*>
99                     aBodyText += rtl::OUString::createFromAscii( ">" );
100 
101                     rtl::OUString aStringValue;
102                     if ( DAVProperties::isUCBDeadProperty( thePropName ) )
103                     {
104                         UCBDeadPropertyValue::toXML( rProperty.value,
105                                                      aStringValue );
106                     }
107                     else
108                     {
109                         rProperty.value >>= aStringValue;
110                     }
111                     aBodyText += aStringValue;
112                     aBodyText += rtl::OUString::createFromAscii( "</" );
113                     aBodyText += rtl::OUString::createFromAscii( thePropName.name );
114                     aBodyText += rtl::OUString::createFromAscii( ">" );
115                 }
116                 else
117                 {
118                     // />
119                     aBodyText += rtl::OUString::createFromAscii( "/>" );
120                 }
121 
122                 lastOp = rProperty.operation;
123             }
124 
125             // </prop></*last operation code*>
126             aBodyText += rtl::OUString::createFromAscii( "</prop></" );
127             aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] );
128             aBodyText += rtl::OUString::createFromAscii( ">" );
129 
130             // add PropPatch xml header in front
131             aBodyText = rtl::OUString::createFromAscii( PROPPATCH_HEADER ) + aBodyText;
132 
133             // add PropPatch xml trailer at end
134             aBodyText += rtl::OUString::createFromAscii( PROPPATCH_TRAILER );
135 
136             body_bkt = SERF_BUCKET_SIMPLE_STRING( rtl::OUStringToOString( aBodyText, RTL_TEXTENCODING_UTF8 ),
137                                                   pSerfBucketAlloc );
138             if ( useChunkedEncoding() )
139             {
140                 body_bkt = serf_bucket_chunk_create( body_bkt, pSerfBucketAlloc );
141             }
142         }
143     }
144 
145     // create serf request
146     serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest,
147                                                                  "PROPPATCH",
148                                                                  getPathStr(),
149                                                                  body_bkt,
150                                                                  pSerfBucketAlloc ) ;
151 
152     // set request header fields
153     serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
154     // general header fields provided by caller
155     setRequestHeaders( hdrs_bkt );
156 
157     // request specific header fields
158     if ( body_bkt != 0 && aBodyText.getLength() > 0 )
159     {
160         if ( useChunkedEncoding() )
161         {
162             serf_bucket_headers_set( hdrs_bkt, "Transfer-Encoding", "chunked");
163         }
164         serf_bucket_headers_set( hdrs_bkt, "Content-Type", "application/xml" );
165         serf_bucket_headers_set( hdrs_bkt, "Content-Length",
166                                  rtl::OUStringToOString( rtl::OUString::valueOf( aBodyText.getLength() ), RTL_TEXTENCODING_UTF8 ) );
167     }
168 
169     return req_bkt;
170 }
171 
172 void SerfPropPatchReqProcImpl::processChunkOfResponseData( const char* /*data*/,
173                                                            apr_size_t /*len*/ )
174 {
175     // nothing to do;
176 }
177 
178 void SerfPropPatchReqProcImpl::handleEndOfResponseData( serf_bucket_t * /*inSerfResponseBucket*/ )
179 {
180     // nothing to do;
181 }
182 
183 } // namespace http_dav_ucp
184