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 // MARKER(update_precomp.py): autogen include statement, do not remove
24 #include "precompiled_stoc.hxx"
25 
26 #include "sal/config.h"
27 
28 #include "stocservices.hxx"
29 
30 #include <new>
31 
32 #include "com/sun/star/lang/IllegalArgumentException.hpp"
33 #include "com/sun/star/lang/XServiceInfo.hpp"
34 #include "com/sun/star/uno/Reference.hxx"
35 #include "com/sun/star/uno/RuntimeException.hpp"
36 #include "com/sun/star/uno/Sequence.hxx"
37 #include "com/sun/star/uno/XInterface.hpp"
38 #include "com/sun/star/uri/XUriReference.hpp"
39 #include "com/sun/star/uri/XUriSchemeParser.hpp"
40 #include "com/sun/star/uri/XVndSunStarExpandUrlReference.hpp"
41 #include "com/sun/star/util/XMacroExpander.hpp"
42 #include "cppuhelper/implbase1.hxx"
43 #include "cppuhelper/implbase2.hxx"
44 #include "cppuhelper/weak.hxx"
45 #include "rtl/textenc.h"
46 #include "rtl/uri.h"
47 #include "rtl/uri.hxx"
48 #include "rtl/ustring.h"
49 #include "rtl/ustring.hxx"
50 #include "sal/types.h"
51 
52 #include "UriReference.hxx"
53 #include "supportsService.hxx"
54 
55 namespace {
56 
57 namespace css = ::com::sun::star;
58 
parseSchemeSpecificPart(::rtl::OUString const & part)59 bool parseSchemeSpecificPart(::rtl::OUString const & part) {
60     // Liberally accepts both an empty opaque_part and an opaque_part that
61     // starts with a non-escaped "/":
62     return part.getLength() == 0
63         || ((::rtl::Uri::decode(
64                  part, ::rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8).
65              getLength())
66             != 0);
67 }
68 
69 class UrlReference:
70     public ::cppu::WeakImplHelper1< css::uri::XVndSunStarExpandUrlReference >
71 {
72 public:
UrlReference(::rtl::OUString const & scheme,::rtl::OUString const & path)73     UrlReference(::rtl::OUString const & scheme, ::rtl::OUString const & path):
74         base_(
75             scheme, false, false, ::rtl::OUString(), path, false,
76             ::rtl::OUString())
77     {}
78 
getUriReference()79     virtual ::rtl::OUString SAL_CALL getUriReference()
80         throw (css::uno::RuntimeException)
81     { return base_.getUriReference(); }
82 
isAbsolute()83     virtual ::sal_Bool SAL_CALL isAbsolute() throw (css::uno::RuntimeException)
84     { return base_.isAbsolute(); }
85 
getScheme()86     virtual ::rtl::OUString SAL_CALL getScheme()
87         throw (css::uno::RuntimeException)
88     { return base_.getScheme(); }
89 
getSchemeSpecificPart()90     virtual ::rtl::OUString SAL_CALL getSchemeSpecificPart()
91         throw (css::uno::RuntimeException)
92     { return base_.getSchemeSpecificPart(); }
93 
isHierarchical()94     virtual ::sal_Bool SAL_CALL isHierarchical()
95         throw (css::uno::RuntimeException)
96     { return base_.isHierarchical(); }
97 
hasAuthority()98     virtual ::sal_Bool SAL_CALL hasAuthority()
99         throw (css::uno::RuntimeException)
100     { return base_.hasAuthority(); }
101 
getAuthority()102     virtual ::rtl::OUString SAL_CALL getAuthority()
103         throw (css::uno::RuntimeException)
104     { return base_.getAuthority(); }
105 
getPath()106     virtual ::rtl::OUString SAL_CALL getPath()
107         throw (css::uno::RuntimeException)
108     { return base_.getPath(); }
109 
hasRelativePath()110     virtual ::sal_Bool SAL_CALL hasRelativePath()
111         throw (css::uno::RuntimeException)
112     { return base_.hasRelativePath(); }
113 
getPathSegmentCount()114     virtual ::sal_Int32 SAL_CALL getPathSegmentCount()
115         throw (css::uno::RuntimeException)
116     { return base_.getPathSegmentCount(); }
117 
getPathSegment(sal_Int32 index)118     virtual ::rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
119         throw (css::uno::RuntimeException)
120     { return base_.getPathSegment(index); }
121 
hasQuery()122     virtual ::sal_Bool SAL_CALL hasQuery() throw (css::uno::RuntimeException)
123     { return base_.hasQuery(); }
124 
getQuery()125     virtual ::rtl::OUString SAL_CALL getQuery()
126         throw (css::uno::RuntimeException)
127     { return base_.getQuery(); }
128 
hasFragment()129     virtual ::sal_Bool SAL_CALL hasFragment() throw (css::uno::RuntimeException)
130     { return base_.hasFragment(); }
131 
getFragment()132     virtual ::rtl::OUString SAL_CALL getFragment()
133         throw (css::uno::RuntimeException)
134     { return base_.getFragment(); }
135 
setFragment(::rtl::OUString const & fragment)136     virtual void SAL_CALL setFragment(::rtl::OUString const & fragment)
137         throw (css::uno::RuntimeException)
138     { base_.setFragment(fragment); }
139 
clearFragment()140     virtual void SAL_CALL clearFragment() throw (css::uno::RuntimeException)
141     { base_.clearFragment(); }
142 
143     virtual ::rtl::OUString SAL_CALL expand(
144         css::uno::Reference< css::util::XMacroExpander > const & expander)
145         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
146 
147 private:
148     UrlReference(UrlReference &); // not defined
149     void operator =(UrlReference); // not defined
150 
~UrlReference()151     virtual ~UrlReference() {}
152 
153     stoc::uriproc::UriReference base_;
154 };
155 
expand(css::uno::Reference<css::util::XMacroExpander> const & expander)156 ::rtl::OUString UrlReference::expand(
157     css::uno::Reference< css::util::XMacroExpander > const & expander)
158     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
159 {
160     OSL_ASSERT(expander.is());
161     return expander->expandMacros(
162         ::rtl::Uri::decode(
163             getPath(), ::rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
164 }
165 
166 class Parser: public ::cppu::WeakImplHelper2<
167     css::lang::XServiceInfo, css::uri::XUriSchemeParser >
168 {
169 public:
Parser()170     Parser() {}
171 
172     virtual ::rtl::OUString SAL_CALL getImplementationName()
173         throw (css::uno::RuntimeException);
174 
175     virtual ::sal_Bool SAL_CALL supportsService(
176         ::rtl::OUString const & serviceName)
177         throw (css::uno::RuntimeException);
178 
179     virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
180     getSupportedServiceNames() throw (css::uno::RuntimeException);
181 
182     virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
183     parse(
184         ::rtl::OUString const & scheme,
185         ::rtl::OUString const & schemeSpecificPart)
186         throw (css::uno::RuntimeException);
187 
188 private:
189     Parser(Parser &); // not defined
190     void operator =(Parser); // not defined
191 
~Parser()192     virtual ~Parser() {}
193 };
194 
getImplementationName()195 ::rtl::OUString Parser::getImplementationName()
196     throw (css::uno::RuntimeException)
197 {
198     return ::stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTexpand::
199         getImplementationName();
200 }
201 
supportsService(::rtl::OUString const & serviceName)202 ::sal_Bool Parser::supportsService(::rtl::OUString const & serviceName)
203     throw (css::uno::RuntimeException)
204 {
205     return ::stoc::uriproc::supportsService(
206         getSupportedServiceNames(), serviceName);
207 }
208 
getSupportedServiceNames()209 css::uno::Sequence< ::rtl::OUString > Parser::getSupportedServiceNames()
210     throw (css::uno::RuntimeException)
211 {
212     return ::stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTexpand::
213         getSupportedServiceNames();
214 }
215 
parse(::rtl::OUString const & scheme,::rtl::OUString const & schemeSpecificPart)216 css::uno::Reference< css::uri::XUriReference > Parser::parse(
217     ::rtl::OUString const & scheme, ::rtl::OUString const & schemeSpecificPart)
218     throw (css::uno::RuntimeException)
219 {
220     if (!parseSchemeSpecificPart(schemeSpecificPart)) {
221         return css::uno::Reference< css::uri::XUriReference >();
222     }
223     try {
224         return new UrlReference(scheme, schemeSpecificPart);
225     } catch (::std::bad_alloc &) {
226         throw css::uno::RuntimeException(
227             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")),
228             css::uno::Reference< css::uno::XInterface >());
229     }
230 }
231 
232 }
233 
234 namespace stoc_services { namespace UriSchemeParser_vndDOTsunDOTstarDOTexpand {
235 
create(css::uno::Reference<css::uno::XComponentContext> const &)236 css::uno::Reference< css::uno::XInterface > create(
237     css::uno::Reference< css::uno::XComponentContext > const &)
238     SAL_THROW((css::uno::Exception))
239 {
240     //TODO: single instance
241     try {
242         return static_cast< ::cppu::OWeakObject * >(new Parser);
243     } catch (::std::bad_alloc &) {
244         throw css::uno::RuntimeException(
245             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")),
246             css::uno::Reference< css::uno::XInterface >());
247     }
248 }
249 
getImplementationName()250 ::rtl::OUString getImplementationName() {
251     return ::rtl::OUString(
252         RTL_CONSTASCII_USTRINGPARAM(
253             "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTexpand"));
254 }
255 
getSupportedServiceNames()256 css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames() {
257     css::uno::Sequence< ::rtl::OUString > s(1);
258     s[0] = ::rtl::OUString(
259         RTL_CONSTASCII_USTRINGPARAM(
260             "com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTexpand"));
261     return s;
262 }
263 
264 } }
265