1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_scripting.hxx"
30 
31 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
32 #include <rtl/ustrbuf.hxx>
33 #include "URIHelper.hxx"
34 
35 #define PRTSTR(x) ::rtl::OUStringToOString(x, RTL_TEXTENCODING_ASCII_US).pData->buffer
36 
37 namespace func_provider
38 {
39 
40 using ::rtl::OUString;
41 namespace uno = ::com::sun::star::uno;
42 namespace ucb = ::com::sun::star::ucb;
43 namespace lang = ::com::sun::star::lang;
44 namespace uri = ::com::sun::star::uri;
45 namespace script = ::com::sun::star::script;
46 
47 static const char SHARE[] = "share";
48 static const char SHARE_URI[] =
49     "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::BaseInstallation}";
50 
51 static const char SHARE_UNO_PACKAGES[] = "share:uno_packages";
52 static const char SHARE_UNO_PACKAGES_URI[] =
53     "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE";
54 
55 static const char USER[] = "user";
56 static const char USER_URI[] =
57     "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}";
58 
59 static const char USER_UNO_PACKAGES[] = "user:uno_packages";
60 static const char USER_UNO_PACKAGES_DIR[] =
61     "/user/uno_packages/cache";
62 
63 static const char DOCUMENT[] = "document";
64 static const char TDOC_SCHEME[] = "vnd.sun.star.tdoc";
65 
66 ScriptingFrameworkURIHelper::ScriptingFrameworkURIHelper(
67     const uno::Reference< uno::XComponentContext >& xContext)
68         throw( uno::RuntimeException )
69 {
70     try
71     {
72         m_xSimpleFileAccess = uno::Reference< ucb::XSimpleFileAccess >(
73             xContext->getServiceManager()->createInstanceWithContext(
74                 OUString::createFromAscii(
75                     "com.sun.star.ucb.SimpleFileAccess"),
76                 xContext), uno::UNO_QUERY_THROW);
77     }
78     catch (uno::Exception&)
79     {
80         OSL_ENSURE(false,
81             "Scripting Framework error initialising XSimpleFileAccess");
82     }
83 
84     try
85     {
86         m_xUriReferenceFactory = uno::Reference< uri::XUriReferenceFactory >(
87             xContext->getServiceManager()->createInstanceWithContext(
88                 OUString::createFromAscii(
89                     "com.sun.star.uri.UriReferenceFactory"),
90             xContext ), uno::UNO_QUERY_THROW );
91     }
92     catch (uno::Exception&)
93     {
94         OSL_ENSURE(false,
95             "Scripting Framework error initialising XUriReferenceFactory");
96     }
97 }
98 
99 ScriptingFrameworkURIHelper::~ScriptingFrameworkURIHelper()
100 {
101     // currently does nothing
102 }
103 
104 void SAL_CALL
105 ScriptingFrameworkURIHelper::initialize(
106     const uno::Sequence < uno::Any >& args )
107 throw ( uno::Exception, uno::RuntimeException )
108 {
109     if ( args.getLength() != 2 ||
110          args[0].getValueType() != ::getCppuType((const OUString*)NULL) ||
111          args[1].getValueType() != ::getCppuType((const OUString*)NULL) )
112     {
113         throw uno::RuntimeException( OUString::createFromAscii(
114             "ScriptingFrameworkURIHelper got invalid argument list" ),
115                 uno::Reference< uno::XInterface >() );
116     }
117 
118     if ( (args[0] >>= m_sLanguage) == sal_False ||
119          (args[1] >>= m_sLocation) == sal_False )
120     {
121         throw uno::RuntimeException( OUString::createFromAscii(
122             "ScriptingFrameworkURIHelper error parsing args" ),
123                 uno::Reference< uno::XInterface >() );
124     }
125 
126     SCRIPTS_PART = OUString::createFromAscii( "/Scripts/" );
127     SCRIPTS_PART = SCRIPTS_PART.concat( m_sLanguage.toAsciiLowerCase() );
128 
129     if ( !initBaseURI() )
130     {
131         throw uno::RuntimeException( OUString::createFromAscii(
132             "ScriptingFrameworkURIHelper cannot find script directory"),
133                 uno::Reference< uno::XInterface >() );
134     }
135 }
136 
137 bool
138 ScriptingFrameworkURIHelper::initBaseURI()
139 {
140     OUString uri, test;
141     bool bAppendScriptsPart = false;
142 
143     if ( m_sLocation.equalsAscii(USER))
144     {
145         test = OUString::createFromAscii(USER);
146         uri = OUString::createFromAscii(USER_URI);
147         bAppendScriptsPart = true;
148     }
149     else if ( m_sLocation.equalsAscii(USER_UNO_PACKAGES))
150     {
151         test = OUString::createFromAscii("uno_packages");
152         uri = OUString::createFromAscii(USER_URI);
153         uri = uri.concat(OUString::createFromAscii(USER_UNO_PACKAGES_DIR));
154     }
155     else if (m_sLocation.equalsAscii(SHARE))
156     {
157         test = OUString::createFromAscii(SHARE);
158         uri = OUString::createFromAscii(SHARE_URI);
159         bAppendScriptsPart = true;
160     }
161     else if (m_sLocation.equalsAscii(SHARE_UNO_PACKAGES))
162     {
163         test = OUString::createFromAscii("uno_packages");
164         uri = OUString::createFromAscii(SHARE_UNO_PACKAGES_URI);
165     }
166     else if (m_sLocation.indexOf(OUString::createFromAscii(TDOC_SCHEME)) == 0)
167     {
168         m_sBaseURI = m_sLocation.concat( SCRIPTS_PART );
169         m_sLocation = OUString::createFromAscii( DOCUMENT );
170         return true;
171     }
172     else
173     {
174         return false;
175     }
176 
177     if ( !m_xSimpleFileAccess->exists( uri ) ||
178          !m_xSimpleFileAccess->isFolder( uri ) )
179     {
180         return false;
181     }
182 
183     uno::Sequence< OUString > children =
184         m_xSimpleFileAccess->getFolderContents( uri, true );
185 
186     for ( sal_Int32 i = 0; i < children.getLength(); i++ )
187     {
188         OUString child = children[i];
189         sal_Int32 idx = child.lastIndexOf(test);
190 
191         // OSL_TRACE("Trying: %s", PRTSTR(child));
192         // OSL_TRACE("idx=%d, testlen=%d, children=%d",
193         //     idx, test.getLength(), child.getLength());
194 
195         if ( idx != -1 && (idx + test.getLength()) == child.getLength() )
196         {
197             // OSL_TRACE("FOUND PATH: %s", PRTSTR(child));
198             if ( bAppendScriptsPart )
199             {
200                 m_sBaseURI = child.concat( SCRIPTS_PART );
201             }
202             else
203             {
204                 m_sBaseURI = child;
205             }
206             return true;
207         }
208     }
209     return false;
210 }
211 
212 OUString
213 ScriptingFrameworkURIHelper::getLanguagePart(const OUString& rStorageURI)
214 {
215     OUString result;
216 
217     sal_Int32 idx = rStorageURI.indexOf(m_sBaseURI);
218     sal_Int32 len = m_sBaseURI.getLength() + 1;
219 
220     if ( idx != -1 )
221     {
222         result = rStorageURI.copy(idx + len);
223         result = result.replace('/', '|');
224     }
225     return result;
226 }
227 
228 OUString
229 ScriptingFrameworkURIHelper::getLanguagePath(const OUString& rLanguagePart)
230 {
231     OUString result;
232     result = rLanguagePart.replace('|', '/');
233     return result;
234 }
235 
236 OUString SAL_CALL
237 ScriptingFrameworkURIHelper::getScriptURI(const OUString& rStorageURI)
238     throw( lang::IllegalArgumentException, uno::RuntimeException )
239 {
240     ::rtl::OUStringBuffer buf(120);
241 
242     buf.appendAscii("vnd.sun.star.script:");
243     buf.append(getLanguagePart(rStorageURI));
244     buf.appendAscii("?language=");
245     buf.append(m_sLanguage);
246     buf.appendAscii("&location=");
247     buf.append(m_sLocation);
248 
249     return buf.makeStringAndClear();
250 }
251 
252 OUString SAL_CALL
253 ScriptingFrameworkURIHelper::getStorageURI(const OUString& rScriptURI)
254     throw( lang::IllegalArgumentException, uno::RuntimeException )
255 {
256     OUString sLanguagePart;
257     try
258     {
259         uno::Reference < uri::XVndSunStarScriptUrl > xURI(
260             m_xUriReferenceFactory->parse( rScriptURI ), uno::UNO_QUERY_THROW );
261         sLanguagePart = xURI->getName();
262     }
263     catch ( uno::Exception& )
264     {
265         throw lang::IllegalArgumentException(
266             OUString::createFromAscii( "Script URI not valid" ),
267                 uno::Reference< uno::XInterface >(), 1 );
268     }
269 
270     ::rtl::OUStringBuffer buf(120);
271     buf.append(m_sBaseURI);
272     buf.append(OUString::createFromAscii("/"));
273     buf.append(getLanguagePath(sLanguagePart));
274 
275     OUString result = buf.makeStringAndClear();
276 
277     return result;
278 }
279 
280 OUString SAL_CALL
281 ScriptingFrameworkURIHelper::getRootStorageURI()
282     throw( uno::RuntimeException )
283 {
284     return m_sBaseURI;
285 }
286 
287 OUString SAL_CALL
288 ScriptingFrameworkURIHelper::getImplementationName()
289     throw( uno::RuntimeException )
290 {
291     return OUString::createFromAscii(
292         "com.sun.star.script.provider.ScriptURIHelper" );
293 }
294 
295 sal_Bool SAL_CALL
296 ScriptingFrameworkURIHelper::supportsService( const OUString& serviceName )
297     throw( uno::RuntimeException )
298 {
299     OUString m_sServiceName = OUString::createFromAscii(
300         "com.sun.star.script.provider.ScriptURIHelper" );
301 
302     if ( serviceName.equals( m_sServiceName ) )
303     {
304         return sal_True;
305     }
306     return sal_False;
307 }
308 
309 uno::Sequence< ::rtl::OUString > SAL_CALL
310 ScriptingFrameworkURIHelper::getSupportedServiceNames()
311     throw( uno::RuntimeException )
312 {
313     ::rtl::OUString serviceNameList[] = {
314         ::rtl::OUString::createFromAscii(
315             "com.sun.star.script.provider.ScriptURIHelper" ) };
316 
317     uno::Sequence< ::rtl::OUString > serviceNames = uno::Sequence <
318         ::rtl::OUString > ( serviceNameList, 1 );
319 
320     return serviceNames;
321 }
322 }
323