SharedContextEvaluator.java revision 2:da1e581c933b
1131087Smarcel/*
2131087Smarcel * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
3215082Simp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4215082Simp *
5138215Smarcel * This code is free software; you can redistribute it and/or modify it
6215082Simp * under the terms of the GNU General Public License version 2 only, as
7239272Sgonzo * published by the Free Software Foundation.  Oracle designates this
8215082Simp * particular file as subject to the "Classpath" exception as provided
9215082Simp * by Oracle in the LICENSE file that accompanied this code.
10215082Simp *
11215082Simp * This code is distributed in the hope that it will be useful, but WITHOUT
12215082Simp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13131087Smarcel * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14136910Sru * version 2 for more details (a copy is included in the LICENSE file that
15137440Smarcel * accompanied this code).
16137440Smarcel *
17137440Smarcel * You should have received a copy of the GNU General Public License version
18137440Smarcel * 2 along with this work; if not, write to the Free Software Foundation,
19137440Smarcel * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20137440Smarcel *
21137440Smarcel * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22137440Smarcel * or visit www.oracle.com if you need additional information or have any
23137440Smarcel * questions.
24137440Smarcel */
25137440Smarcel
26137440Smarcelpackage jdk.nashorn.internal.test.framework;
27137440Smarcel
28137440Smarcelimport static jdk.nashorn.tools.Shell.COMPILATION_ERROR;
29251858Semasteimport static jdk.nashorn.tools.Shell.RUNTIME_ERROR;
30137440Smarcelimport static jdk.nashorn.tools.Shell.SUCCESS;
31137440Smarcel
32138215Smarcelimport java.io.File;
33138215Smarcelimport java.io.IOException;
34137440Smarcelimport java.io.OutputStream;
35137440Smarcelimport java.io.PrintWriter;
36137440Smarcelimport jdk.nashorn.api.scripting.NashornException;
37137440Smarcelimport jdk.nashorn.internal.runtime.Context;
38137440Smarcelimport jdk.nashorn.internal.runtime.ErrorManager;
39137440Smarcelimport jdk.nashorn.internal.runtime.ScriptFunction;
40137440Smarcelimport jdk.nashorn.internal.runtime.ScriptObject;
41137440Smarcelimport jdk.nashorn.internal.runtime.ScriptRuntime;
42137440Smarcelimport jdk.nashorn.internal.runtime.options.Options;
43137440Smarcel
44137440Smarcel/**
45137440Smarcel * A script evaluator that shares a single Nashorn Context instance to run
46137440Smarcel * scripts many times on it.
47137440Smarcel */
48138383Smarcelpublic final class SharedContextEvaluator implements ScriptEvaluator {
49138383Smarcel    // The shared Nashorn Context
50137440Smarcel    private final Context context;
51137440Smarcel
52137440Smarcel    // We can't replace output and error streams after Context is created
53137440Smarcel    // So, we create these delegating streams - so that we can replace underlying
54137440Smarcel    // delegate streams for each script run call
55137440Smarcel    private final DelegatingOutputStream ctxOut;
56137440Smarcel    private final DelegatingOutputStream ctxErr;
57134154Sdavidxu
58131087Smarcel    private static class DelegatingOutputStream extends OutputStream {
59141911Sobrien        private OutputStream underlying;
60141911Sobrien
61141911Sobrien        public DelegatingOutputStream(final OutputStream out) {
62141911Sobrien            this.underlying = out;
63141911Sobrien        }
64138380Smarcel
65138215Smarcel        @Override
66138215Smarcel        public void close() throws IOException {
67138215Smarcel            underlying.close();
68134154Sdavidxu        }
69134154Sdavidxu
70251858Semaste        @Override
71138215Smarcel        public void flush() throws IOException {
72131087Smarcel            underlying.flush();
73131087Smarcel        }
74131087Smarcel
75131087Smarcel        @Override
76131087Smarcel        public void write(byte[] b) throws IOException {
77131087Smarcel            underlying.write(b);
78131087Smarcel        }
79131087Smarcel
80131087Smarcel        @Override
81        public void write(byte[] b, int off, int len) throws IOException {
82            underlying.write(b, off, len);
83        }
84
85        @Override
86        public void write(int b) throws IOException {
87            underlying.write(b);
88        }
89
90        void setDelegatee(OutputStream stream) {
91            this.underlying = stream;
92        }
93    }
94
95    /**
96     * SharedContextEvaluator constructor
97     * @param args initial script arguments to create shared context
98     */
99    public SharedContextEvaluator(final String[] args) {
100        this.ctxOut = new DelegatingOutputStream(System.out);
101        this.ctxErr = new DelegatingOutputStream(System.err);
102        PrintWriter wout = new PrintWriter(ctxOut, true);
103        PrintWriter werr = new PrintWriter(ctxErr, true);
104        Options options = new Options("nashorn", werr);
105        options.process(args);
106        ErrorManager errors = new ErrorManager(werr);
107        this.context = new Context(options, errors, wout, werr);
108    }
109
110    @Override
111    public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
112        final ScriptObject oldGlobal = Context.getGlobal();
113        try {
114            ctxOut.setDelegatee(out);
115            ctxErr.setDelegatee(err);
116            final ErrorManager errors = context.getErrors();
117            final ScriptObject global = context.createGlobal();
118            Context.setGlobal(global);
119
120            // For each file on the command line.
121            for (final String fileName : args) {
122                if (fileName.startsWith("-")) {
123                    // ignore options in shared context mode (which was initialized upfront!)
124                    continue;
125                }
126                final File file = new File(fileName);
127                ScriptFunction script = context.compileScript(fileName, file.toURI().toURL(), global, context._strict);
128                if (script == null || errors.getNumberOfErrors() != 0) {
129                    return COMPILATION_ERROR;
130                }
131
132                try {
133                    ScriptRuntime.apply(script, global);
134                } catch (final NashornException e) {
135                    errors.error(e.toString());
136                    if (context._dump_on_error) {
137                        e.printStackTrace(context.getErr());
138                    }
139
140                    return RUNTIME_ERROR;
141                }
142            }
143        } finally {
144            context.getOut().flush();
145            context.getErr().flush();
146            Context.setGlobal(oldGlobal);
147        }
148
149        return SUCCESS;
150    }
151}
152