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