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 #include "webdavuseragent.hxx"
36 
37 #include <osl/mutex.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <com/sun/star/beans/NamedValue.hpp>
41 #include <com/sun/star/container/XNameAccess.hpp>
42 
43 using namespace com::sun::star;
44 using namespace http_dav_ucp;
45 
46 
47 rtl::OUString &WebDAVUserAgent::operator()() const
48 {
49     rtl::OUStringBuffer aBuffer;
50     aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "$ooName/$ooSetupVersion" ));
51 #if OSL_DEBUG_LEVEL > 0
52 #ifdef APR_VERSION
53     aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " apr/" APR_VERSION ));
54 #endif
55 
56 #ifdef APR_UTIL_VERSION
57     aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " apr-util/" APR_UTIL_VERSION ));
58 #endif
59 
60 #ifdef SERF_VERSION
61     aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " serf/" SERF_VERSION ));
62 #endif
63 #endif
64     static rtl::OUString aUserAgent( aBuffer.makeStringAndClear() );
65     return aUserAgent;
66 }
67 
68 //=========================================================================
69 //=========================================================================
70 //
71 // ContentProvider Implementation.
72 //
73 //=========================================================================
74 //=========================================================================
75 
76 ContentProvider::ContentProvider(
77                 const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
78 : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
79   m_xDAVSessionFactory( new DAVSessionFactory() ),
80   m_pProps( 0 )
81 {
82     static bool bInit = false;
83     if ( bInit )
84         return;
85     bInit = true;
86     try
87     {
88         uno::Reference< uno::XComponentContext > xContext(
89             ::comphelper::getProcessComponentContext() );
90         uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
91             xContext->getServiceManager()->createInstanceWithContext(
92                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
93                                   "com.sun.star.configuration.ConfigurationProvider")), xContext),
94             uno::UNO_QUERY_THROW );
95 
96         beans::NamedValue aNodePath;
97         aNodePath.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
98         aNodePath.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup/Product"));
99 
100         uno::Sequence< uno::Any > aArgs( 1 );
101         aArgs[0] <<= aNodePath;
102 
103         uno::Reference< container::XNameAccess > xConfigAccess(
104             xConfigProvider->createInstanceWithArguments(
105                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
106                     "com.sun.star.configuration.ConfigurationAccess")), aArgs),
107             uno::UNO_QUERY_THROW );
108 
109         rtl::OUString aVal;
110         xConfigAccess->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooName"))) >>= aVal;
111 
112         rtl::OUString &aUserAgent = WebDAVUserAgent::get();
113         sal_Int32 nIndex = aUserAgent.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "$ooName" ) );
114         if ( !aVal.getLength() || nIndex == -1 )
115             return;
116         aUserAgent = aUserAgent.replaceAt( nIndex, RTL_CONSTASCII_LENGTH( "$ooName" ), aVal );
117 
118         xConfigAccess->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupVersion"))) >>= aVal;
119         nIndex = aUserAgent.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "$ooSetupVersion" ) );
120         if ( !aVal.getLength() || nIndex == -1 )
121             return;
122         aUserAgent = aUserAgent.replaceAt( nIndex, RTL_CONSTASCII_LENGTH( "$ooSetupVersion" ), aVal );
123 
124     }
125     catch ( const uno::Exception &e )
126     {
127         OSL_TRACE( "ContentProvider -caught exception! %s",
128                    rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
129         (void) e;
130     }
131 }
132 
133 //=========================================================================
134 // virtual
135 ContentProvider::~ContentProvider()
136 {
137 	delete m_pProps;
138 }
139 
140 //=========================================================================
141 //
142 // XInterface methods.
143 //
144 //=========================================================================
145 
146 XINTERFACE_IMPL_3( ContentProvider,
147                    lang::XTypeProvider,
148                    lang::XServiceInfo,
149                    ucb::XContentProvider );
150 
151 //=========================================================================
152 //
153 // XTypeProvider methods.
154 //
155 //=========================================================================
156 
157 XTYPEPROVIDER_IMPL_3( ContentProvider,
158                       lang::XTypeProvider,
159                       lang::XServiceInfo,
160                       ucb::XContentProvider );
161 
162 //=========================================================================
163 //
164 // XServiceInfo methods.
165 //
166 //=========================================================================
167 
168 XSERVICEINFO_IMPL_1( ContentProvider,
169                      rtl::OUString::createFromAscii(
170 			 			"com.sun.star.comp.WebDAVContentProvider" ),
171                      rtl::OUString::createFromAscii(
172 				 		WEBDAV_CONTENT_PROVIDER_SERVICE_NAME ) );
173 
174 //=========================================================================
175 //
176 // Service factory implementation.
177 //
178 //=========================================================================
179 
180 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
181 
182 //=========================================================================
183 //
184 // XContentProvider methods.
185 //
186 //=========================================================================
187 
188 // virtual
189 uno::Reference< ucb::XContent > SAL_CALL
190 ContentProvider::queryContent(
191             const uno::Reference<
192                     ucb::XContentIdentifier >& Identifier )
193     throw( ucb::IllegalIdentifierException,
194            uno::RuntimeException )
195 {
196 	// Check URL scheme...
197 
198     const rtl::OUString aScheme
199         = Identifier->getContentProviderScheme().toAsciiLowerCase();
200     if ( !aScheme.equalsAsciiL(
201             RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) &&
202          !aScheme.equalsAsciiL(
203             RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) &&
204          !aScheme.equalsAsciiL(
205             RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) &&
206          !aScheme.equalsAsciiL(
207             RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) &&
208          !aScheme.equalsAsciiL(
209             RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
210         throw ucb::IllegalIdentifierException();
211 
212 	// Normalize URL and create new Id, if nessacary.
213     rtl::OUString aURL = Identifier->getContentIdentifier();
214 
215     // At least: <scheme> + "://"
216     if ( aURL.getLength() < ( aScheme.getLength() + 3 ) )
217         throw ucb::IllegalIdentifierException();
218 
219     if ( ( aURL.getStr()[ aScheme.getLength() ]     != sal_Unicode( ':' ) ) ||
220          ( aURL.getStr()[ aScheme.getLength() + 1 ] != sal_Unicode( '/' ) ) ||
221          ( aURL.getStr()[ aScheme.getLength() + 2 ] != sal_Unicode( '/' ) ) )
222         throw ucb::IllegalIdentifierException();
223 
224     uno::Reference< ucb::XContentIdentifier > xCanonicId;
225 
226     bool bNewId = false;
227     if ( aScheme.equalsAsciiL(
228             RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
229     {
230         aURL = aURL.replaceAt( 0,
231                                WEBDAV_URL_SCHEME_LENGTH,
232                                rtl::OUString::createFromAscii(
233                                                     HTTP_URL_SCHEME ) );
234         bNewId = true;
235     }
236     else if ( aScheme.equalsAsciiL(
237             RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
238     {
239         aURL = aURL.replaceAt( 0,
240                                DAV_URL_SCHEME_LENGTH,
241                                rtl::OUString::createFromAscii(
242                                                     HTTP_URL_SCHEME ) );
243         bNewId = true;
244     }
245     else if ( aScheme.equalsAsciiL(
246             RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
247     {
248         aURL = aURL.replaceAt( 0,
249                                DAVS_URL_SCHEME_LENGTH,
250                                rtl::OUString::createFromAscii(
251                                                     HTTPS_URL_SCHEME ) );
252         bNewId = true;
253     }
254 
255     sal_Int32 nPos = aURL.lastIndexOf( '/' );
256 	if ( nPos != aURL.getLength() - 1 )
257 	{
258 		// Find second slash in URL.
259 		nPos = aURL.indexOf( '/', aURL.indexOf( '/' ) + 1 );
260 		if ( nPos == -1 )
261             throw ucb::IllegalIdentifierException();
262 
263 		nPos = aURL.indexOf( '/', nPos + 1 );
264 		if ( nPos == -1 )
265 		{
266             aURL += rtl::OUString::createFromAscii( "/" );
267             bNewId = true;
268 		}
269 	}
270 
271     if ( bNewId )
272         xCanonicId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
273     else
274         xCanonicId = Identifier;
275 
276 	osl::MutexGuard aGuard( m_aMutex );
277 
278 	// Check, if a content with given id already exists...
279     uno::Reference< ucb::XContent > xContent
280 		= queryExistingContent( xCanonicId ).get();
281 	if ( xContent.is() )
282 		return xContent;
283 
284 	// Create a new content.
285 
286 	try
287 	{
288         xContent = new ::http_dav_ucp::Content(
289                         m_xSMgr, this, xCanonicId, m_xDAVSessionFactory );
290         registerNewContent( xContent );
291 	}
292     catch ( ucb::ContentCreationException const & )
293 	{
294         throw ucb::IllegalIdentifierException();
295 	}
296 
297 	if ( !xContent->getIdentifier().is() )
298         throw ucb::IllegalIdentifierException();
299 
300 	return xContent;
301 }
302 
303