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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26 
27 /**************************************************************************
28 								TODO
29  **************************************************************************
30 
31  *************************************************************************/
32 #include <ucbhelper/contentidentifier.hxx>
33 #include "webdavprovider.hxx"
34 #include "webdavcontent.hxx"
35 
36 #include <osl/mutex.hxx>
37 
38 using namespace com::sun::star;
39 using namespace http_dav_ucp;
40 
41 //=========================================================================
42 //=========================================================================
43 //
44 // ContentProvider Implementation.
45 //
46 //=========================================================================
47 //=========================================================================
48 
49 ContentProvider::ContentProvider(
50                 const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
51 : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
52   m_xDAVSessionFactory( new DAVSessionFactory() ),
53   m_pProps( 0 )
54 {
55 }
56 
57 //=========================================================================
58 // virtual
59 ContentProvider::~ContentProvider()
60 {
61 	delete m_pProps;
62 }
63 
64 //=========================================================================
65 //
66 // XInterface methods.
67 //
68 //=========================================================================
69 
70 XINTERFACE_IMPL_3( ContentProvider,
71                    lang::XTypeProvider,
72                    lang::XServiceInfo,
73                    ucb::XContentProvider );
74 
75 //=========================================================================
76 //
77 // XTypeProvider methods.
78 //
79 //=========================================================================
80 
81 XTYPEPROVIDER_IMPL_3( ContentProvider,
82                       lang::XTypeProvider,
83                       lang::XServiceInfo,
84                       ucb::XContentProvider );
85 
86 //=========================================================================
87 //
88 // XServiceInfo methods.
89 //
90 //=========================================================================
91 
92 XSERVICEINFO_IMPL_1( ContentProvider,
93                      rtl::OUString::createFromAscii(
94 			 			"com.sun.star.comp.WebDAVContentProvider" ),
95                      rtl::OUString::createFromAscii(
96 				 		WEBDAV_CONTENT_PROVIDER_SERVICE_NAME ) );
97 
98 //=========================================================================
99 //
100 // Service factory implementation.
101 //
102 //=========================================================================
103 
104 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
105 
106 //=========================================================================
107 //
108 // XContentProvider methods.
109 //
110 //=========================================================================
111 
112 // virtual
113 uno::Reference< ucb::XContent > SAL_CALL
114 ContentProvider::queryContent(
115             const uno::Reference<
116                     ucb::XContentIdentifier >& Identifier )
117     throw( ucb::IllegalIdentifierException,
118            uno::RuntimeException )
119 {
120 	// Check URL scheme...
121 
122     const rtl::OUString aScheme
123         = Identifier->getContentProviderScheme().toAsciiLowerCase();
124     if ( !aScheme.equalsAsciiL(
125             RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) &&
126          !aScheme.equalsAsciiL(
127             RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) &&
128          !aScheme.equalsAsciiL(
129             RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) &&
130          !aScheme.equalsAsciiL(
131             RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) &&
132          !aScheme.equalsAsciiL(
133             RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
134         throw ucb::IllegalIdentifierException();
135 
136 	// Normalize URL and create new Id, if nessacary.
137     rtl::OUString aURL = Identifier->getContentIdentifier();
138 
139     // At least: <scheme> + "://"
140     if ( aURL.getLength() < ( aScheme.getLength() + 3 ) )
141         throw ucb::IllegalIdentifierException();
142 
143     if ( ( aURL.getStr()[ aScheme.getLength() ]     != sal_Unicode( ':' ) ) ||
144          ( aURL.getStr()[ aScheme.getLength() + 1 ] != sal_Unicode( '/' ) ) ||
145          ( aURL.getStr()[ aScheme.getLength() + 2 ] != sal_Unicode( '/' ) ) )
146         throw ucb::IllegalIdentifierException();
147 
148     uno::Reference< ucb::XContentIdentifier > xCanonicId;
149 
150     bool bNewId = false;
151     if ( aScheme.equalsAsciiL(
152             RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
153     {
154         aURL = aURL.replaceAt( 0,
155                                WEBDAV_URL_SCHEME_LENGTH,
156                                rtl::OUString::createFromAscii(
157                                                     HTTP_URL_SCHEME ) );
158         bNewId = true;
159     }
160     else if ( aScheme.equalsAsciiL(
161             RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
162     {
163         aURL = aURL.replaceAt( 0,
164                                DAV_URL_SCHEME_LENGTH,
165                                rtl::OUString::createFromAscii(
166                                                     HTTP_URL_SCHEME ) );
167         bNewId = true;
168     }
169     else if ( aScheme.equalsAsciiL(
170             RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
171     {
172         aURL = aURL.replaceAt( 0,
173                                DAVS_URL_SCHEME_LENGTH,
174                                rtl::OUString::createFromAscii(
175                                                     HTTPS_URL_SCHEME ) );
176         bNewId = true;
177     }
178 
179     sal_Int32 nPos = aURL.lastIndexOf( '/' );
180 	if ( nPos != aURL.getLength() - 1 )
181 	{
182 		// Find second slash in URL.
183 		nPos = aURL.indexOf( '/', aURL.indexOf( '/' ) + 1 );
184 		if ( nPos == -1 )
185             throw ucb::IllegalIdentifierException();
186 
187 		nPos = aURL.indexOf( '/', nPos + 1 );
188 		if ( nPos == -1 )
189 		{
190             aURL += rtl::OUString::createFromAscii( "/" );
191             bNewId = true;
192 		}
193 	}
194 
195     if ( bNewId )
196         xCanonicId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
197     else
198         xCanonicId = Identifier;
199 
200 	osl::MutexGuard aGuard( m_aMutex );
201 
202 	// Check, if a content with given id already exists...
203     uno::Reference< ucb::XContent > xContent
204 		= queryExistingContent( xCanonicId ).get();
205 	if ( xContent.is() )
206 		return xContent;
207 
208 	// Create a new content.
209 
210 	try
211 	{
212         xContent = new ::http_dav_ucp::Content(
213                         m_xSMgr, this, xCanonicId, m_xDAVSessionFactory );
214         registerNewContent( xContent );
215 	}
216     catch ( ucb::ContentCreationException const & )
217 	{
218         throw ucb::IllegalIdentifierException();
219 	}
220 
221 	if ( !xContent->getIdentifier().is() )
222         throw ucb::IllegalIdentifierException();
223 
224 	return xContent;
225 }
226 
227