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_scripting.hxx"
26 
27 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
28 #include <rtl/ustrbuf.hxx>
29 #include "URIHelper.hxx"
30 
31 #define PRTSTR(x) ::rtl::OUStringToOString(x, RTL_TEXTENCODING_ASCII_US).pData->buffer
32 
33 namespace func_provider
34 {
35 
36 using ::rtl::OUString;
37 namespace uno = ::com::sun::star::uno;
38 namespace ucb = ::com::sun::star::ucb;
39 namespace lang = ::com::sun::star::lang;
40 namespace uri = ::com::sun::star::uri;
41 namespace script = ::com::sun::star::script;
42 
43 static const char SHARE[] = "share";
44 static const char SHARE_URI[] =
45     "vnd.sun.star.expand:$$OOO_BASE_DIR";
46 //    "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::BaseInstallation}";
47 
48 static const char SHARE_UNO_PACKAGES[] = "share:uno_packages";
49 static const char SHARE_UNO_PACKAGES_URI[] =
50     "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE";
51 
52 static const char USER[] = "user";
53 static const char USER_URI[] =
54     "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}";
55 
56 static const char USER_UNO_PACKAGES[] = "user:uno_packages";
57 static const char USER_UNO_PACKAGES_DIR[] =
58     "/user/uno_packages/cache";
59 
60 static const char DOCUMENT[] = "document";
61 static const char TDOC_SCHEME[] = "vnd.sun.star.tdoc";
62 
ScriptingFrameworkURIHelper(const uno::Reference<uno::XComponentContext> & xContext)63 ScriptingFrameworkURIHelper::ScriptingFrameworkURIHelper(
64     const uno::Reference< uno::XComponentContext >& xContext)
65         throw( uno::RuntimeException )
66 {
67     try
68     {
69         m_xSimpleFileAccess = uno::Reference< ucb::XSimpleFileAccess >(
70             xContext->getServiceManager()->createInstanceWithContext(
71                 OUString::createFromAscii(
72                     "com.sun.star.ucb.SimpleFileAccess"),
73                 xContext), uno::UNO_QUERY_THROW);
74     }
75     catch (uno::Exception&)
76     {
77         OSL_ENSURE(false,
78             "Scripting Framework error initialising XSimpleFileAccess");
79     }
80 
81     try
82     {
83         m_xUriReferenceFactory = uno::Reference< uri::XUriReferenceFactory >(
84             xContext->getServiceManager()->createInstanceWithContext(
85                 OUString::createFromAscii(
86                     "com.sun.star.uri.UriReferenceFactory"),
87             xContext ), uno::UNO_QUERY_THROW );
88     }
89     catch (uno::Exception&)
90     {
91         OSL_ENSURE(false,
92             "Scripting Framework error initialising XUriReferenceFactory");
93     }
94 }
95 
~ScriptingFrameworkURIHelper()96 ScriptingFrameworkURIHelper::~ScriptingFrameworkURIHelper()
97 {
98     // currently does nothing
99 }
100 
101 void SAL_CALL
initialize(const uno::Sequence<uno::Any> & args)102 ScriptingFrameworkURIHelper::initialize(
103     const uno::Sequence < uno::Any >& args )
104 throw ( uno::Exception, uno::RuntimeException )
105 {
106     if ( args.getLength() != 2 ||
107          args[0].getValueType() != ::getCppuType((const OUString*)NULL) ||
108          args[1].getValueType() != ::getCppuType((const OUString*)NULL) )
109     {
110         throw uno::RuntimeException( OUString::createFromAscii(
111             "ScriptingFrameworkURIHelper got invalid argument list" ),
112                 uno::Reference< uno::XInterface >() );
113     }
114 
115     if ( (args[0] >>= m_sLanguage) == sal_False ||
116          (args[1] >>= m_sLocation) == sal_False )
117     {
118         throw uno::RuntimeException( OUString::createFromAscii(
119             "ScriptingFrameworkURIHelper error parsing args" ),
120                 uno::Reference< uno::XInterface >() );
121     }
122 
123     SCRIPTS_PART = OUString::createFromAscii( "/Scripts/" );
124     SCRIPTS_PART = SCRIPTS_PART.concat( m_sLanguage.toAsciiLowerCase() );
125 
126     if ( !initBaseURI() )
127     {
128         throw uno::RuntimeException( OUString::createFromAscii(
129             "ScriptingFrameworkURIHelper cannot find script directory"),
130                 uno::Reference< uno::XInterface >() );
131     }
132 }
133 
134 bool
initBaseURI()135 ScriptingFrameworkURIHelper::initBaseURI()
136 {
137     OUString uri, test;
138     bool bAppendScriptsPart = false;
139 
140     if ( m_sLocation.equalsAscii(USER))
141     {
142         test = OUString::createFromAscii(USER);
143         uri = OUString::createFromAscii(USER_URI);
144         bAppendScriptsPart = true;
145     }
146     else if ( m_sLocation.equalsAscii(USER_UNO_PACKAGES))
147     {
148         test = OUString::createFromAscii("uno_packages");
149         uri = OUString::createFromAscii(USER_URI);
150         uri = uri.concat(OUString::createFromAscii(USER_UNO_PACKAGES_DIR));
151     }
152     else if (m_sLocation.equalsAscii(SHARE))
153     {
154         test = OUString::createFromAscii(SHARE);
155         uri = OUString::createFromAscii(SHARE_URI);
156         bAppendScriptsPart = true;
157     }
158     else if (m_sLocation.equalsAscii(SHARE_UNO_PACKAGES))
159     {
160         test = OUString::createFromAscii("uno_packages");
161         uri = OUString::createFromAscii(SHARE_UNO_PACKAGES_URI);
162     }
163     else if (m_sLocation.indexOf(OUString::createFromAscii(TDOC_SCHEME)) == 0)
164     {
165         m_sBaseURI = m_sLocation.concat( SCRIPTS_PART );
166         m_sLocation = OUString::createFromAscii( DOCUMENT );
167         return true;
168     }
169     else
170     {
171         return false;
172     }
173 
174     if ( !m_xSimpleFileAccess->exists( uri ) ||
175          !m_xSimpleFileAccess->isFolder( uri ) )
176     {
177         return false;
178     }
179 
180     uno::Sequence< OUString > children =
181         m_xSimpleFileAccess->getFolderContents( uri, true );
182 
183     for ( sal_Int32 i = 0; i < children.getLength(); i++ )
184     {
185         OUString child = children[i];
186         sal_Int32 idx = child.lastIndexOf(test);
187 
188         // OSL_TRACE("Trying: %s", PRTSTR(child));
189         // OSL_TRACE("idx=%d, testlen=%d, children=%d",
190         //     idx, test.getLength(), child.getLength());
191 
192         if ( idx != -1 && (idx + test.getLength()) == child.getLength() )
193         {
194             // OSL_TRACE("FOUND PATH: %s", PRTSTR(child));
195             if ( bAppendScriptsPart )
196             {
197                 m_sBaseURI = child.concat( SCRIPTS_PART );
198             }
199             else
200             {
201                 m_sBaseURI = child;
202             }
203             return true;
204         }
205     }
206     return false;
207 }
208 
209 OUString
getLanguagePart(const OUString & rStorageURI)210 ScriptingFrameworkURIHelper::getLanguagePart(const OUString& rStorageURI)
211 {
212     OUString result;
213 
214     sal_Int32 idx = rStorageURI.indexOf(m_sBaseURI);
215     sal_Int32 len = m_sBaseURI.getLength() + 1;
216 
217     if ( idx != -1 )
218     {
219         result = rStorageURI.copy(idx + len);
220         result = result.replace('/', '|');
221     }
222     return result;
223 }
224 
225 OUString
getLanguagePath(const OUString & rLanguagePart)226 ScriptingFrameworkURIHelper::getLanguagePath(const OUString& rLanguagePart)
227 {
228     OUString result;
229     result = rLanguagePart.replace('|', '/');
230     return result;
231 }
232 
233 OUString SAL_CALL
getScriptURI(const OUString & rStorageURI)234 ScriptingFrameworkURIHelper::getScriptURI(const OUString& rStorageURI)
235     throw( lang::IllegalArgumentException, uno::RuntimeException )
236 {
237     ::rtl::OUStringBuffer buf(120);
238 
239     buf.appendAscii("vnd.sun.star.script:");
240     buf.append(getLanguagePart(rStorageURI));
241     buf.appendAscii("?language=");
242     buf.append(m_sLanguage);
243     buf.appendAscii("&location=");
244     buf.append(m_sLocation);
245 
246     return buf.makeStringAndClear();
247 }
248 
249 OUString SAL_CALL
getStorageURI(const OUString & rScriptURI)250 ScriptingFrameworkURIHelper::getStorageURI(const OUString& rScriptURI)
251     throw( lang::IllegalArgumentException, uno::RuntimeException )
252 {
253     OUString sLanguagePart;
254     try
255     {
256         uno::Reference < uri::XVndSunStarScriptUrl > xURI(
257             m_xUriReferenceFactory->parse( rScriptURI ), uno::UNO_QUERY_THROW );
258         sLanguagePart = xURI->getName();
259     }
260     catch ( uno::Exception& )
261     {
262         throw lang::IllegalArgumentException(
263             OUString::createFromAscii( "Script URI not valid" ),
264                 uno::Reference< uno::XInterface >(), 1 );
265     }
266 
267     ::rtl::OUStringBuffer buf(120);
268     buf.append(m_sBaseURI);
269     buf.append(OUString::createFromAscii("/"));
270     buf.append(getLanguagePath(sLanguagePart));
271 
272     OUString result = buf.makeStringAndClear();
273 
274     return result;
275 }
276 
277 OUString SAL_CALL
getRootStorageURI()278 ScriptingFrameworkURIHelper::getRootStorageURI()
279     throw( uno::RuntimeException )
280 {
281     return m_sBaseURI;
282 }
283 
284 OUString SAL_CALL
getImplementationName()285 ScriptingFrameworkURIHelper::getImplementationName()
286     throw( uno::RuntimeException )
287 {
288     return OUString::createFromAscii(
289         "com.sun.star.script.provider.ScriptURIHelper" );
290 }
291 
292 sal_Bool SAL_CALL
supportsService(const OUString & serviceName)293 ScriptingFrameworkURIHelper::supportsService( const OUString& serviceName )
294     throw( uno::RuntimeException )
295 {
296     OUString m_sServiceName = OUString::createFromAscii(
297         "com.sun.star.script.provider.ScriptURIHelper" );
298 
299     if ( serviceName.equals( m_sServiceName ) )
300     {
301         return sal_True;
302     }
303     return sal_False;
304 }
305 
306 uno::Sequence< ::rtl::OUString > SAL_CALL
getSupportedServiceNames()307 ScriptingFrameworkURIHelper::getSupportedServiceNames()
308     throw( uno::RuntimeException )
309 {
310     ::rtl::OUString serviceNameList[] = {
311         ::rtl::OUString::createFromAscii(
312             "com.sun.star.script.provider.ScriptURIHelper" ) };
313 
314     uno::Sequence< ::rtl::OUString > serviceNames = uno::Sequence <
315         ::rtl::OUString > ( serviceNameList, 1 );
316 
317     return serviceNames;
318 }
319 }
320