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