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