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 68 public _ScriptProviderForJava( XComponentContext ctx ) 69 { 70 super (ctx, "Java"); 71 } 72 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 93 public boolean hasScriptEditor() 94 { 95 return false; 96 } 97 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 */ 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; 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 aParams 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 InvocationTargetException If the running script throws an exception 177 * this information is captured and rethrown as this exception type. 178 */ 179 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