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 package com.sun.star.script.framework.provider.java;
24 
25 import com.sun.star.frame.XModel;
26 import com.sun.star.comp.loader.FactoryHelper;
27 import com.sun.star.document.XScriptInvocationContext;
28 import com.sun.star.uno.XComponentContext;
29 import com.sun.star.lang.XMultiComponentFactory;
30 import com.sun.star.lang.XMultiServiceFactory;
31 import com.sun.star.lang.XSingleServiceFactory;
32 import com.sun.star.registry.XRegistryKey;
33 import com.sun.star.uno.Type;
34 import com.sun.star.uno.Any;
35 
36 import java.util.ArrayList;
37 import java.util.Map;
38 import java.net.MalformedURLException;
39 
40 import com.sun.star.script.provider.XScriptContext;
41 import com.sun.star.script.provider.XScript;
42 import com.sun.star.script.provider.ScriptExceptionRaisedException;
43 import com.sun.star.script.provider.ScriptFrameworkErrorException;
44 import com.sun.star.script.provider.ScriptFrameworkErrorType;
45 
46 import com.sun.star.script.framework.container.ScriptMetaData;
47 
48 import com.sun.star.script.framework.provider.*;
49 import com.sun.star.script.framework.log.LogUtils;
50 /**
51  *  Description of the Class
52  *
53  * @author     Noel Power
54  * @created    August 2, 2002
55  */
56 public class ScriptProviderForJava
57 {
58     /**
59      *  Description of the Class
60      *
61      * @author     Noel Power
62      * @created    August 2, 2002
63      */
64     public static class _ScriptProviderForJava extends ScriptProvider
65     {
66         private Resolver m_resolutionPolicy = new StrictResolver();
67 
_ScriptProviderForJava( XComponentContext ctx )68         public _ScriptProviderForJava( XComponentContext ctx )
69         {
70             super (ctx, "Java");
71         }
72 
getScript( String scriptURI )73         public XScript getScript( /*IN*/String scriptURI )
74             throws com.sun.star.uno.RuntimeException,
75                    ScriptFrameworkErrorException
76         {
77             ScriptMetaData scriptData = null;
78             scriptData = getScriptData( scriptURI );
79             ScriptImpl script = null;
80             try
81             {
82                 script = new ScriptImpl( m_xContext, m_resolutionPolicy, scriptData, m_xModel, m_xInvocContext );
83                 return script;
84             }
85             catch ( com.sun.star.uno.RuntimeException re )
86             {
87                 throw new ScriptFrameworkErrorException( "Failed to create script object: " + re.getMessage(),
88                     null, scriptData.getLanguageName(), language, ScriptFrameworkErrorType.UNKNOWN );
89             }
90 
91         }
92 
hasScriptEditor()93         public boolean hasScriptEditor()
94         {
95             return false;
96         }
97 
getScriptEditor()98         public ScriptEditor getScriptEditor()
99         {
100             return null;
101         }
102     }
103 
104     /**
105      * Returns a factory for creating the service.
106      * This method is called by the <code>JavaLoader</code>
107      * <p>
108      *
109      * @param  implName      the name of the implementation for which a service is desired
110      * @param  multiFactory  the service manager to be used if needed
111      * @param  regKey        the registryKey
112      * @return               returns a <code>XSingleServiceFactory</code> for creating
113      *                          the component
114      * @see                  com.sun.star.comp.loader.JavaLoader
115      */
__getServiceFactory( String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey )116     public static XSingleServiceFactory __getServiceFactory( String implName,
117             XMultiServiceFactory multiFactory,
118             XRegistryKey regKey )
119     {
120         XSingleServiceFactory xSingleServiceFactory = null;
121 
122         if ( implName.equals( ScriptProviderForJava._ScriptProviderForJava.class.getName() ) )
123         {
124               xSingleServiceFactory = FactoryHelper.getServiceFactory(
125                 ScriptProviderForJava._ScriptProviderForJava.class,
126                 "com.sun.star.script.provider.ScriptProviderForJava",
127                 multiFactory,
128                 regKey );
129         }
130 
131         return xSingleServiceFactory;
132     }
133 }
134 
135 class ScriptImpl implements XScript
136 {
137     private ScriptMetaData metaData;
138     private XComponentContext m_xContext;
139     private XModel m_xModel;
140     private XScriptInvocationContext m_xInvocContext;
141     private XMultiComponentFactory m_xMultiComponentFactory;
142     private Resolver m_resolutionPolicy;
ScriptImpl( XComponentContext ctx, Resolver resolver, ScriptMetaData metaData, XModel xModel, XScriptInvocationContext xInvocContext )143     ScriptImpl( XComponentContext ctx, Resolver resolver, ScriptMetaData metaData, XModel xModel, XScriptInvocationContext xInvocContext ) throws com.sun.star.uno.RuntimeException
144     {
145         this.metaData = metaData;
146         this.m_xContext = ctx;
147         this.m_xModel = xModel;
148         this.m_xInvocContext = xInvocContext;
149         this.m_resolutionPolicy = resolver;
150         try
151         {
152             this.m_xMultiComponentFactory = m_xContext.getServiceManager();
153         }
154         catch ( Exception e )
155         {
156             LogUtils.DEBUG( LogUtils.getTrace( e ) );
157             throw new com.sun.star.uno.RuntimeException(
158                 "Error constructing  ScriptProvider: "
159                 + e.getMessage() );
160         }
161 
162         LogUtils.DEBUG("ScriptImpl [java] script data = " + metaData );
163     }
164         /**
165          *  Invoke
166          *
167          *
168          * @param params            All parameters; pure, out params are undefined in
169          *                      sequence, i.e., the value has to be ignored by the callee
170          * @param aOutParamIndex    Out indices
171          * @param aOutParam         Out parameters
172          * @returns                 The value returned from the function being invoked
173          * @throws IllegalArgumentException If there is no matching script name
174          * @throws CannotConvertException   If args do not match or cannot be converted
175          *                              the those of the invokee
176          * @throws com.sun.star.reflection.InvocationTargetException If the running script throws an exception
177          *              this information is captured and rethrown as this exception type.
178          */
179 
invoke( Object[] params, short[][] aOutParamIndex, Object[][] aOutParam )180         public Object invoke(
181                                      /*IN*/Object[]  params,
182                                      /*OUT*/short[][]  aOutParamIndex,
183                                      /*OUT*/Object[][]  aOutParam )
184 
185         throws  ScriptFrameworkErrorException, com.sun.star.reflection.InvocationTargetException
186         {
187             LogUtils.DEBUG( "** ScriptProviderForJava::invoke: Starting..." );
188 
189             // Initialise the out paramters - not used at the moment
190             aOutParamIndex[0] = new short[0];
191             aOutParam[0] = new Object[0];
192 
193 
194             Map languageProps = metaData.getLanguageProperties();
195 
196             ScriptDescriptor scriptDesc =
197                 new ScriptDescriptor( metaData.getLanguageName() );
198 
199             ClassLoader scriptLoader = null;
200 
201             try {
202                 LogUtils.DEBUG( "Classloader starting..." );
203                 scriptLoader = ClassLoaderFactory.getURLClassLoader(
204                         metaData );
205                 LogUtils.DEBUG( "Classloader finished..." );
206             }
207             catch (MalformedURLException mfe )
208             {
209                 // Framework error
210                 throw new ScriptFrameworkErrorException(
211                     mfe.getMessage(), null,
212                     metaData.getLanguageName(), metaData.getLanguage(),
213                     ScriptFrameworkErrorType.MALFORMED_URL );
214             }
215             catch (NoSuitableClassLoaderException ncl )
216             {
217                 // Framework error
218                 throw new ScriptFrameworkErrorException(
219                     ncl.getMessage(), null,
220                     metaData.getLanguageName(), metaData.getLanguage(),
221                     ScriptFrameworkErrorType.UNKNOWN );
222             }
223             catch (ArrayStoreException e )
224             {
225                 // Framework error
226                 throw new ScriptFrameworkErrorException(
227                     e.getMessage(), null,
228                     metaData.getLanguageName(), metaData.getLanguage(),
229                     ScriptFrameworkErrorType.UNKNOWN );
230             }
231 
232             ArrayList invocationArgList = new ArrayList();
233             Object[] invocationArgs = null;
234 
235             LogUtils.DEBUG( "Parameter Mapping..." );
236 
237             // Setup Context Object
238             XScriptContext xSc = ScriptContext.createContext(m_xModel, m_xInvocContext,
239                 m_xContext, m_xMultiComponentFactory);
240             scriptDesc.addArgumentType( XScriptContext.class );
241             invocationArgList.add( xSc );
242 
243             for ( int i = 0; i < params.length; i++ )
244             {
245                 scriptDesc.addArgumentType( params[ i ].getClass() );
246                 invocationArgList.add( params[ i ] );
247             }
248 
249             if ( !invocationArgList.isEmpty() )
250             {
251                 invocationArgs = invocationArgList.toArray();
252             }
253 
254 
255 
256             LogUtils.DEBUG( "ScriptProxy starting... " );
257             ScriptProxy script = null;
258             try
259             {
260                 String className = metaData.getLanguageName().substring( 0,
261                     metaData.getLanguageName().lastIndexOf( '.' ) );
262                 LogUtils.DEBUG( "About to load Class " + className + " starting... " );
263 
264                 long start = new java.util.Date().getTime();
265                 Class c = scriptLoader.loadClass( className );
266                 long end = new java.util.Date().getTime();
267 
268                 LogUtils.DEBUG("loadClass took: " + String.valueOf(end - start) +
269                       "milliseconds");
270 
271                 try
272                 {
273                     LogUtils.DEBUG( "class loaded ... " );
274                     script = m_resolutionPolicy.getProxy( scriptDesc, c );
275                     LogUtils.DEBUG( "script resolved ... " );
276                 }
277                 catch( NoSuchMethodException e )
278                 {
279                     // Framework error
280                     throw new ScriptFrameworkErrorException(
281                         e.getMessage(), null,
282                         metaData.getLanguageName(), metaData.getLanguage(),
283                         ScriptFrameworkErrorType.NO_SUCH_SCRIPT );
284                 }
285             }
286             catch ( ClassNotFoundException e )
287             {
288                 // Framework error
289                 throw new ScriptFrameworkErrorException(
290                     e.getMessage(), null,
291                     metaData.getLanguageName(), metaData.getLanguage(),
292                     ScriptFrameworkErrorType.NO_SUCH_SCRIPT );
293             }
294 
295             LogUtils.DEBUG( "Starting Invoke on Proxy ..." );
296             Object result = null;
297 
298             try
299             {
300                 long start = new java.util.Date().getTime();
301                 result = script.invoke( invocationArgs );
302                 long end = new java.util.Date().getTime();
303 
304                 LogUtils.DEBUG("invoke took: " +
305                     String.valueOf(end - start) + "milliseconds");
306             }
307             catch ( java.lang.IllegalArgumentException iae )
308             {
309                 throw new ScriptFrameworkErrorException(
310                     iae.getMessage(), null,
311                     metaData.getLanguageName(), metaData.getLanguage(),
312                     ScriptFrameworkErrorType.UNKNOWN );
313 
314             }
315             catch ( java.lang.IllegalAccessException ia )
316             {
317                 throw new ScriptFrameworkErrorException(
318                     ia.getMessage(), null,
319                     metaData.getLanguageName(), metaData.getLanguage(),
320                     ScriptFrameworkErrorType.UNKNOWN );
321             }
322             catch ( java.lang.reflect.InvocationTargetException ite )
323             {
324                 Throwable targetException = ite.getTargetException();
325                 ScriptExceptionRaisedException se =
326                     new ScriptExceptionRaisedException(
327                         targetException.toString() );
328                 se.lineNum = -1;
329                 se.scriptName = metaData.getLanguageName();
330                 se.language = "Java";
331                 se.exceptionType = targetException.getClass().getName();
332                 throw new com.sun.star.reflection.InvocationTargetException(
333                     "Scripting Framework error executing script ", null, se );
334             }
335             catch ( Exception unknown )
336             {
337                 ScriptExceptionRaisedException se =
338                     new ScriptExceptionRaisedException(
339                         unknown.toString() );
340                 se.lineNum = -1;
341                 se.scriptName = metaData.getLanguageName();
342                 se.language = "Java";
343                 se.exceptionType = unknown.getClass().getName();
344                 throw new com.sun.star.reflection.InvocationTargetException(
345                     "Scripting Framework error executing script ", null, se );
346             }
347             if ( result == null )
348             {
349                 LogUtils.DEBUG( "Got Nothing Back" );
350                 // in the case where there is no return type
351                 Any voidAny = new Any(new Type(), null);
352                 result = voidAny;
353             }
354             else
355             {
356                 LogUtils.DEBUG( "Got object " + result );
357             }
358             return result;
359         }
360 }
361