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 webdav_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           !aScheme.equalsAsciiL(
135              RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) )       )
136         throw ucb::IllegalIdentifierException();
137 
138 	// Normalize URL and create new Id, if nessacary.
139     rtl::OUString aURL = Identifier->getContentIdentifier();
140 
141     // At least: <scheme> + "://"
142     if ( aURL.getLength() < ( aScheme.getLength() + 3 ) )
143         throw ucb::IllegalIdentifierException();
144 
145     if ( ( aURL.getStr()[ aScheme.getLength() ]     != sal_Unicode( ':' ) ) ||
146          ( aURL.getStr()[ aScheme.getLength() + 1 ] != sal_Unicode( '/' ) ) ||
147          ( aURL.getStr()[ aScheme.getLength() + 2 ] != sal_Unicode( '/' ) ) )
148         throw ucb::IllegalIdentifierException();
149 
150     uno::Reference< ucb::XContentIdentifier > xCanonicId;
151 
152     bool bNewId = false;
153     if ( aScheme.equalsAsciiL(
154             RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
155     {
156         aURL = aURL.replaceAt( 0,
157                                WEBDAV_URL_SCHEME_LENGTH,
158                                rtl::OUString::createFromAscii(
159                                                     HTTP_URL_SCHEME ) );
160         bNewId = true;
161     }
162     else if ( aScheme.equalsAsciiL(
163             RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
164     {
165         aURL = aURL.replaceAt( 0,
166                                DAV_URL_SCHEME_LENGTH,
167                                rtl::OUString::createFromAscii(
168                                                     HTTP_URL_SCHEME ) );
169         bNewId = true;
170     }
171     else if ( aScheme.equalsAsciiL(
172             RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
173     {
174         aURL = aURL.replaceAt( 0,
175                                DAVS_URL_SCHEME_LENGTH,
176                                rtl::OUString::createFromAscii(
177                                                     HTTPS_URL_SCHEME ) );
178         bNewId = true;
179     }
180 
181     sal_Int32 nPos = aURL.lastIndexOf( '/' );
182 	if ( nPos != aURL.getLength() - 1 )
183 	{
184 		// Find second slash in URL.
185 		nPos = aURL.indexOf( '/', aURL.indexOf( '/' ) + 1 );
186 		if ( nPos == -1 )
187             throw ucb::IllegalIdentifierException();
188 
189 		nPos = aURL.indexOf( '/', nPos + 1 );
190 		if ( nPos == -1 )
191 		{
192             aURL += rtl::OUString::createFromAscii( "/" );
193             bNewId = true;
194 		}
195 	}
196 
197     if ( bNewId )
198         xCanonicId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
199     else
200         xCanonicId = Identifier;
201 
202 	osl::MutexGuard aGuard( m_aMutex );
203 
204 	// Check, if a content with given id already exists...
205     uno::Reference< ucb::XContent > xContent
206 		= queryExistingContent( xCanonicId ).get();
207 	if ( xContent.is() )
208 		return xContent;
209 
210 	// Create a new content.
211 
212 	try
213 	{
214         xContent = new ::webdav_ucp::Content(
215                         m_xSMgr, this, xCanonicId, m_xDAVSessionFactory );
216         registerNewContent( xContent );
217 	}
218     catch ( ucb::ContentCreationException const & )
219 	{
220         throw ucb::IllegalIdentifierException();
221 	}
222 
223 	if ( !xContent->getIdentifier().is() )
224         throw ucb::IllegalIdentifierException();
225 
226 	return xContent;
227 }
228 
229