1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_ucb.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <string.h>
28*b1cdbd2cSJim Jagielski #include "DAVProperties.hxx"
29*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski using namespace http_dav_ucp;
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::CREATIONDATE =
34*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:creationdate" );
35*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::DISPLAYNAME =
36*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:displayname" );
37*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::GETCONTENTLANGUAGE =
38*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:getcontentlanguage" );
39*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::GETCONTENTLENGTH =
40*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:getcontentlength" );
41*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::GETCONTENTTYPE =
42*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:getcontenttype" );
43*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::GETETAG =
44*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:getetag" );
45*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::GETLASTMODIFIED =
46*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:getlastmodified" );
47*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::LOCKDISCOVERY =
48*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:lockdiscovery" );
49*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::RESOURCETYPE =
50*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:resourcetype" );
51*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::SUPPORTEDLOCK =
52*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii( "DAV:supportedlock" );
53*b1cdbd2cSJim Jagielski 
54*b1cdbd2cSJim Jagielski const ::rtl::OUString DAVProperties::EXECUTABLE =
55*b1cdbd2cSJim Jagielski                 ::rtl::OUString::createFromAscii(
56*b1cdbd2cSJim Jagielski                                 "http://apache.org/dav/props/executable" );
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
59*b1cdbd2cSJim Jagielski // static
createSerfPropName(const rtl::OUString & rFullName,SerfPropName & rName)60*b1cdbd2cSJim Jagielski void DAVProperties::createSerfPropName( const rtl::OUString & rFullName,
61*b1cdbd2cSJim Jagielski                                         SerfPropName & rName )
62*b1cdbd2cSJim Jagielski {
63*b1cdbd2cSJim Jagielski     if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DAV:" ) ) == 0 )
64*b1cdbd2cSJim Jagielski     {
65*b1cdbd2cSJim Jagielski         rName.nspace = "DAV:";
66*b1cdbd2cSJim Jagielski         rName.name
67*b1cdbd2cSJim Jagielski             = strdup( rtl::OUStringToOString(
68*b1cdbd2cSJim Jagielski                         rFullName.copy( RTL_CONSTASCII_LENGTH( "DAV:" ) ),
69*b1cdbd2cSJim Jagielski                                         RTL_TEXTENCODING_UTF8 ).getStr() );
70*b1cdbd2cSJim Jagielski     }
71*b1cdbd2cSJim Jagielski     else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
72*b1cdbd2cSJim Jagielski                 "http://apache.org/dav/props/" ) ) == 0 )
73*b1cdbd2cSJim Jagielski     {
74*b1cdbd2cSJim Jagielski         rName.nspace = "http://apache.org/dav/props/";
75*b1cdbd2cSJim Jagielski         rName.name
76*b1cdbd2cSJim Jagielski             = strdup( rtl::OUStringToOString(
77*b1cdbd2cSJim Jagielski                         rFullName.copy(
78*b1cdbd2cSJim Jagielski                             RTL_CONSTASCII_LENGTH(
79*b1cdbd2cSJim Jagielski                                 "http://apache.org/dav/props/" ) ),
80*b1cdbd2cSJim Jagielski                             RTL_TEXTENCODING_UTF8 ).getStr() );
81*b1cdbd2cSJim Jagielski     }
82*b1cdbd2cSJim Jagielski     else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
83*b1cdbd2cSJim Jagielski                 "http://ucb.openoffice.org/dav/props/" ) ) == 0 )
84*b1cdbd2cSJim Jagielski     {
85*b1cdbd2cSJim Jagielski         rName.nspace = "http://ucb.openoffice.org/dav/props/";
86*b1cdbd2cSJim Jagielski         rName.name
87*b1cdbd2cSJim Jagielski             = strdup( rtl::OUStringToOString(
88*b1cdbd2cSJim Jagielski                         rFullName.copy(
89*b1cdbd2cSJim Jagielski                             RTL_CONSTASCII_LENGTH(
90*b1cdbd2cSJim Jagielski                                 "http://ucb.openoffice.org/dav/props/" ) ),
91*b1cdbd2cSJim Jagielski                             RTL_TEXTENCODING_UTF8 ).getStr() );
92*b1cdbd2cSJim Jagielski     }
93*b1cdbd2cSJim Jagielski     else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
94*b1cdbd2cSJim Jagielski                 "<prop:" ) ) == 0 )
95*b1cdbd2cSJim Jagielski     {
96*b1cdbd2cSJim Jagielski         // Support for 3rd party namespaces/props
97*b1cdbd2cSJim Jagielski 
98*b1cdbd2cSJim Jagielski         rtl::OString aFullName
99*b1cdbd2cSJim Jagielski             = rtl::OUStringToOString( rFullName, RTL_TEXTENCODING_UTF8 );
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski         // Format: <prop:the_propname xmlns:prop="the_namespace">
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski         sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
104*b1cdbd2cSJim Jagielski         sal_Int32 nLen = aFullName.indexOf( ' ' ) - nStart;
105*b1cdbd2cSJim Jagielski         rName.name = strdup( aFullName.copy( nStart, nLen ).getStr() );
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski         nStart = aFullName.indexOf( '=', nStart + nLen ) + 2; // after ="
108*b1cdbd2cSJim Jagielski         nLen = aFullName.getLength() - RTL_CONSTASCII_LENGTH( "\">" ) - nStart;
109*b1cdbd2cSJim Jagielski         rName.nspace = strdup( aFullName.copy( nStart, nLen ).getStr() );
110*b1cdbd2cSJim Jagielski     }
111*b1cdbd2cSJim Jagielski     else
112*b1cdbd2cSJim Jagielski     {
113*b1cdbd2cSJim Jagielski         // Add our namespace to our own properties.
114*b1cdbd2cSJim Jagielski         rName.nspace = "http://ucb.openoffice.org/dav/props/";
115*b1cdbd2cSJim Jagielski         rName.name
116*b1cdbd2cSJim Jagielski             = strdup( rtl::OUStringToOString( rFullName,
117*b1cdbd2cSJim Jagielski                                               RTL_TEXTENCODING_UTF8 ).getStr() );
118*b1cdbd2cSJim Jagielski     }
119*b1cdbd2cSJim Jagielski }
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
122*b1cdbd2cSJim Jagielski // static
createUCBPropName(const char * nspace,const char * name,rtl::OUString & rFullName)123*b1cdbd2cSJim Jagielski void DAVProperties::createUCBPropName( const char * nspace,
124*b1cdbd2cSJim Jagielski                                        const char * name,
125*b1cdbd2cSJim Jagielski                                        rtl::OUString & rFullName )
126*b1cdbd2cSJim Jagielski {
127*b1cdbd2cSJim Jagielski     rtl::OUString aNameSpace
128*b1cdbd2cSJim Jagielski         = rtl::OStringToOUString( nspace, RTL_TEXTENCODING_UTF8 );
129*b1cdbd2cSJim Jagielski     rtl::OUString aName
130*b1cdbd2cSJim Jagielski         = rtl::OStringToOUString( name,   RTL_TEXTENCODING_UTF8 );
131*b1cdbd2cSJim Jagielski 
132*b1cdbd2cSJim Jagielski     if ( !aNameSpace.getLength() )
133*b1cdbd2cSJim Jagielski     {
134*b1cdbd2cSJim Jagielski         // Some servers send XML without proper namespaces. Assume "DAV:"
135*b1cdbd2cSJim Jagielski         // in this case, if name is a well-known dav property name.
136*b1cdbd2cSJim Jagielski         // Although this is not 100% correct, it solves many problems.
137*b1cdbd2cSJim Jagielski 
138*b1cdbd2cSJim Jagielski         if ( DAVProperties::RESOURCETYPE.matchIgnoreAsciiCase( aName, 4 )  ||
139*b1cdbd2cSJim Jagielski              DAVProperties::SUPPORTEDLOCK.matchIgnoreAsciiCase( aName, 4 ) ||
140*b1cdbd2cSJim Jagielski              DAVProperties::LOCKDISCOVERY.matchIgnoreAsciiCase( aName, 4 ) ||
141*b1cdbd2cSJim Jagielski              DAVProperties::CREATIONDATE.matchIgnoreAsciiCase( aName, 4 ) ||
142*b1cdbd2cSJim Jagielski              DAVProperties::DISPLAYNAME.matchIgnoreAsciiCase( aName, 4 ) ||
143*b1cdbd2cSJim Jagielski              DAVProperties::GETCONTENTLANGUAGE.matchIgnoreAsciiCase( aName, 4 ) ||
144*b1cdbd2cSJim Jagielski              DAVProperties::GETCONTENTLENGTH.matchIgnoreAsciiCase( aName, 4 ) ||
145*b1cdbd2cSJim Jagielski              DAVProperties::GETCONTENTTYPE.matchIgnoreAsciiCase( aName, 4 ) ||
146*b1cdbd2cSJim Jagielski              DAVProperties::GETETAG.matchIgnoreAsciiCase( aName, 4 ) ||
147*b1cdbd2cSJim Jagielski              DAVProperties::GETLASTMODIFIED.matchIgnoreAsciiCase( aName, 4 ) )
148*b1cdbd2cSJim Jagielski         {
149*b1cdbd2cSJim Jagielski             aNameSpace = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DAV:" ) );
150*b1cdbd2cSJim Jagielski         }
151*b1cdbd2cSJim Jagielski     }
152*b1cdbd2cSJim Jagielski 
153*b1cdbd2cSJim Jagielski     // Note: Concatenating strings BEFORE comparing against known namespaces
154*b1cdbd2cSJim Jagielski     //       is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ).
155*b1cdbd2cSJim Jagielski     rFullName  = aNameSpace;
156*b1cdbd2cSJim Jagielski     rFullName += aName;
157*b1cdbd2cSJim Jagielski 
158*b1cdbd2cSJim Jagielski     if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
159*b1cdbd2cSJim Jagielski                 "DAV:" ) ) == 0 )
160*b1cdbd2cSJim Jagielski     {
161*b1cdbd2cSJim Jagielski         // Okay, Just concat strings.
162*b1cdbd2cSJim Jagielski     }
163*b1cdbd2cSJim Jagielski     else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
164*b1cdbd2cSJim Jagielski                 "http://apache.org/dav/props/" ) ) == 0 )
165*b1cdbd2cSJim Jagielski     {
166*b1cdbd2cSJim Jagielski         // Okay, Just concat strings.
167*b1cdbd2cSJim Jagielski     }
168*b1cdbd2cSJim Jagielski     else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
169*b1cdbd2cSJim Jagielski                 "http://ucb.openoffice.org/dav/props/" ) ) == 0 )
170*b1cdbd2cSJim Jagielski     {
171*b1cdbd2cSJim Jagielski         // Remove namespace from our own properties.
172*b1cdbd2cSJim Jagielski         rFullName = rFullName.copy(
173*b1cdbd2cSJim Jagielski                         RTL_CONSTASCII_LENGTH(
174*b1cdbd2cSJim Jagielski                             "http://ucb.openoffice.org/dav/props/" ) );
175*b1cdbd2cSJim Jagielski     }
176*b1cdbd2cSJim Jagielski     else
177*b1cdbd2cSJim Jagielski     {
178*b1cdbd2cSJim Jagielski         // Create property name that encodes, namespace and name ( XML ).
179*b1cdbd2cSJim Jagielski         rFullName  = rtl::OUString::createFromAscii( "<prop:" );
180*b1cdbd2cSJim Jagielski         rFullName += aName;
181*b1cdbd2cSJim Jagielski         rFullName += rtl::OUString::createFromAscii( " xmlns:prop=\"" );
182*b1cdbd2cSJim Jagielski         rFullName += aNameSpace;
183*b1cdbd2cSJim Jagielski         rFullName += rtl::OUString::createFromAscii( "\">" );
184*b1cdbd2cSJim Jagielski     }
185*b1cdbd2cSJim Jagielski }
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
188*b1cdbd2cSJim Jagielski // static
isUCBDeadProperty(const SerfPropName & rName)189*b1cdbd2cSJim Jagielski bool DAVProperties::isUCBDeadProperty( const SerfPropName & rName )
190*b1cdbd2cSJim Jagielski {
191*b1cdbd2cSJim Jagielski     return ( rName.nspace &&
192*b1cdbd2cSJim Jagielski              ( rtl_str_compareIgnoreAsciiCase(
193*b1cdbd2cSJim Jagielski                  rName.nspace, "http://ucb.openoffice.org/dav/props/" )
194*b1cdbd2cSJim Jagielski                == 0 ) );
195*b1cdbd2cSJim Jagielski }
196*b1cdbd2cSJim Jagielski 
isUCBSpecialProperty(const rtl::OUString & rFullName,rtl::OUString & rParsedName)197*b1cdbd2cSJim Jagielski bool DAVProperties::isUCBSpecialProperty(const rtl::OUString& rFullName, rtl::OUString& rParsedName)
198*b1cdbd2cSJim Jagielski {
199*b1cdbd2cSJim Jagielski     sal_Int32 nLen = rFullName.getLength();
200*b1cdbd2cSJim Jagielski     if ( nLen <= 0 ||
201*b1cdbd2cSJim Jagielski             !rFullName.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "<prop:" ) ) ||
202*b1cdbd2cSJim Jagielski             !rFullName.endsWithAsciiL( RTL_CONSTASCII_STRINGPARAM( "\">" ) ) )
203*b1cdbd2cSJim Jagielski         return false;
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski     sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
206*b1cdbd2cSJim Jagielski     sal_Int32 nEnd = rFullName.indexOf( sal_Unicode( ' ' ), nStart );
207*b1cdbd2cSJim Jagielski     if ( nEnd == -1 )
208*b1cdbd2cSJim Jagielski         return false;
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski     rtl::OUString sPropName = rFullName.copy( nStart, nEnd - nStart );
211*b1cdbd2cSJim Jagielski     if ( !sPropName.getLength() )
212*b1cdbd2cSJim Jagielski         return false;
213*b1cdbd2cSJim Jagielski 
214*b1cdbd2cSJim Jagielski     // TODO skip whitespaces?
215*b1cdbd2cSJim Jagielski     if ( !rFullName.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "xmlns:prop=\"" ), ++nEnd ) )
216*b1cdbd2cSJim Jagielski         return false;
217*b1cdbd2cSJim Jagielski 
218*b1cdbd2cSJim Jagielski     nStart = nEnd + RTL_CONSTASCII_LENGTH( "xmlns:prop=\"" );
219*b1cdbd2cSJim Jagielski     nEnd = rFullName.indexOf( sal_Unicode( '"' ), nStart );
220*b1cdbd2cSJim Jagielski     if ( nEnd != nLen - RTL_CONSTASCII_LENGTH( "\">" ) )
221*b1cdbd2cSJim Jagielski         return false;
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski     rtl::OUString sNamesp = rFullName.copy( nStart, nEnd - nStart );
224*b1cdbd2cSJim Jagielski     if ( !( nLen = sNamesp.getLength() ) )
225*b1cdbd2cSJim Jagielski         return false;
226*b1cdbd2cSJim Jagielski 
227*b1cdbd2cSJim Jagielski     rtl::OUStringBuffer aBuff( sNamesp );
228*b1cdbd2cSJim Jagielski     if ( sNamesp[nLen - 1] != '/' )
229*b1cdbd2cSJim Jagielski         aBuff.append( sal_Unicode( '/' ) );
230*b1cdbd2cSJim Jagielski     aBuff.append( sPropName );
231*b1cdbd2cSJim Jagielski     rParsedName = aBuff.makeStringAndClear();
232*b1cdbd2cSJim Jagielski 
233*b1cdbd2cSJim Jagielski     return rParsedName.getLength();
234*b1cdbd2cSJim Jagielski }
235