jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.m
changeset 34523 7ac19a1f8316
parent 34522 fa15f1bdaec2
child 34524 10f859612e02
equal deleted inserted replaced
34522:fa15f1bdaec2 34523:7ac19a1f8316
     1 /*
       
     2  * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 #import "AppleScriptExecutionContext.h"
       
    27 
       
    28 #import <Carbon/Carbon.h>
       
    29 
       
    30 #import "AS_NS_ConversionUtils.h"
       
    31 
       
    32 
       
    33 @implementation AppleScriptExecutionContext
       
    34 
       
    35 @synthesize source;
       
    36 @synthesize context;
       
    37 @synthesize error;
       
    38 @synthesize returnValue;
       
    39 
       
    40 - (id) init:(NSString *)sourceIn context:(id)contextIn {
       
    41     self = [super init];
       
    42     if (!self) return self;
       
    43 
       
    44     self.source = sourceIn;
       
    45     self.context = contextIn;
       
    46     self.returnValue = nil;
       
    47     self.error = nil;
       
    48 
       
    49     return self;
       
    50 }
       
    51 
       
    52 - (id) initWithSource:(NSString *)sourceIn context:(NSDictionary *)contextIn {
       
    53     self = [self init:sourceIn context:contextIn];
       
    54     isFile = NO;
       
    55     return self;
       
    56 }
       
    57 
       
    58 - (id) initWithFile:(NSString *)filenameIn context:(NSDictionary *)contextIn {
       
    59     self = [self init:filenameIn context:contextIn];
       
    60     isFile = YES;
       
    61     return self;
       
    62 }
       
    63 
       
    64 - (void) dealloc {
       
    65     self.source = nil;
       
    66     self.context = nil;
       
    67     self.returnValue = nil;
       
    68     self.error = nil;
       
    69 
       
    70     [super dealloc];
       
    71 }
       
    72 
       
    73 - (NSAppleScript *) scriptFromURL {
       
    74     NSURL *url = [NSURL URLWithString:source];
       
    75     NSDictionary *err = nil;
       
    76     NSAppleScript *script = [[[NSAppleScript alloc] initWithContentsOfURL:url error:(&err)] autorelease];
       
    77     if (err != nil) self.error = err;
       
    78     return script;
       
    79 }
       
    80 
       
    81 - (NSAppleScript *) scriptFromSource {
       
    82     return [[[NSAppleScript alloc] initWithSource:source] autorelease];
       
    83 }
       
    84 
       
    85 - (NSAppleEventDescriptor *) functionInvocationEvent {
       
    86     NSString *function = [[context objectForKey:@"javax_script_function"] description];
       
    87     if (function == nil) return nil;
       
    88 
       
    89     // wrap the arg in an array if it is not already a list
       
    90     id args = [context objectForKey:@"javax_script_argv"];
       
    91     if (![args isKindOfClass:[NSArray class]]) {
       
    92         args = [NSArray arrayWithObjects:args, nil];
       
    93     }
       
    94 
       
    95     // triangulate our target
       
    96     int pid = [[NSProcessInfo processInfo] processIdentifier];
       
    97     NSAppleEventDescriptor* targetAddress = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID
       
    98                                                                                            bytes:&pid
       
    99                                                                                           length:sizeof(pid)];
       
   100 
       
   101     // create the event to call a subroutine in the script
       
   102     NSAppleEventDescriptor* event = [[NSAppleEventDescriptor alloc] initWithEventClass:kASAppleScriptSuite
       
   103                                                                                eventID:kASSubroutineEvent
       
   104                                                                       targetDescriptor:targetAddress
       
   105                                                                               returnID:kAutoGenerateReturnID
       
   106                                                                          transactionID:kAnyTransactionID];
       
   107 
       
   108     // set up the handler
       
   109     NSAppleEventDescriptor* subroutineDescriptor = [NSAppleEventDescriptor descriptorWithString:[function lowercaseString]];
       
   110     [event setParamDescriptor:subroutineDescriptor forKeyword:keyASSubroutineName];
       
   111 
       
   112     // set up the arguments
       
   113     [event setParamDescriptor:[args aeDescriptorValue] forKeyword:keyDirectObject];
       
   114 
       
   115     return [event autorelease];
       
   116 }
       
   117 
       
   118 - (void) invoke {
       
   119     // create our script
       
   120     NSAppleScript *script = isFile ? [self scriptFromURL] : [self scriptFromSource];
       
   121     if (self.error != nil) return;
       
   122 
       
   123     // find out if we have a subroutine to call
       
   124     NSAppleEventDescriptor *fxnInvkEvt = [self functionInvocationEvent];
       
   125 
       
   126     // exec!
       
   127     NSAppleEventDescriptor *desc = nil;
       
   128     NSDictionary *err = nil;
       
   129     if (fxnInvkEvt == nil) {
       
   130         desc = [script executeAndReturnError:(&err)];
       
   131     } else {
       
   132         desc = [script executeAppleEvent:fxnInvkEvt error:(&err)];
       
   133     }
       
   134 
       
   135     // if we encountered an exception, stash and bail
       
   136     if (err != nil) {
       
   137         self.error = err;
       
   138         return;
       
   139     }
       
   140 
       
   141     // convert to NSObjects, and return in ivar
       
   142     self.returnValue = [desc objCObjectValue];
       
   143 }
       
   144 
       
   145 - (id) invokeWithEnv:(JNIEnv *)env {
       
   146     BOOL useAnyThread = [@"any-thread" isEqual:[context valueForKey:@"javax_script_threading"]];
       
   147 
       
   148     // check if we are already on the AppKit thread, if desired
       
   149     if(pthread_main_np() || useAnyThread) {
       
   150         [self invoke];
       
   151     } else {
       
   152         [JNFRunLoop performOnMainThread:@selector(invoke) on:self withObject:nil waitUntilDone:YES];
       
   153     }
       
   154 
       
   155     // if we have an exception parked in our ivar, snarf the message (if there is one), and toss a ScriptException
       
   156     if (self.error != nil) {
       
   157         NSString *asErrString = [self.error objectForKey:NSAppleScriptErrorMessage];
       
   158         if (!asErrString) asErrString = @"AppleScriptEngine failed to execute script."; // usually when we fail to load a file
       
   159         [JNFException raise:env as:"javax/script/ScriptException" reason:[asErrString UTF8String]];
       
   160     }
       
   161 
       
   162     return self.returnValue;
       
   163 }
       
   164 
       
   165 @end