author | sundar |
Wed, 27 Sep 2017 18:40:37 +0530 | |
changeset 47277 | 69c3639a49a6 |
parent 47216 | 71c04702a3d5 |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
45725 | 2 |
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. |
16147 | 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 |
package jdk.nashorn.internal.runtime; |
|
27 |
||
28 |
import java.io.ByteArrayOutputStream; |
|
29 |
import java.io.File; |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
30 |
import java.io.FileNotFoundException; |
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
31 |
import java.io.FileOutputStream; |
16147 | 32 |
import java.io.IOError; |
33 |
import java.io.IOException; |
|
34 |
import java.io.InputStream; |
|
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
35 |
import java.io.PrintWriter; |
16147 | 36 |
import java.io.Reader; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
37 |
import java.lang.ref.WeakReference; |
16147 | 38 |
import java.net.MalformedURLException; |
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
39 |
import java.net.URI; |
16147 | 40 |
import java.net.URISyntaxException; |
41 |
import java.net.URL; |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
42 |
import java.net.URLConnection; |
16147 | 43 |
import java.nio.charset.Charset; |
44 |
import java.nio.charset.StandardCharsets; |
|
45 |
import java.nio.file.Files; |
|
46 |
import java.nio.file.Path; |
|
47 |
import java.nio.file.Paths; |
|
23767 | 48 |
import java.security.MessageDigest; |
49 |
import java.security.NoSuchAlgorithmException; |
|
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
50 |
import java.time.LocalDateTime; |
16147 | 51 |
import java.util.Arrays; |
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
52 |
import java.util.Base64; |
16147 | 53 |
import java.util.Objects; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
54 |
import java.util.WeakHashMap; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
55 |
import jdk.nashorn.api.scripting.URLReader; |
16147 | 56 |
import jdk.nashorn.internal.parser.Token; |
24769 | 57 |
import jdk.nashorn.internal.runtime.logging.DebugLogger; |
58 |
import jdk.nashorn.internal.runtime.logging.Loggable; |
|
59 |
import jdk.nashorn.internal.runtime.logging.Logger; |
|
16147 | 60 |
/** |
61 |
* Source objects track the origin of JavaScript entities. |
|
62 |
*/ |
|
24769 | 63 |
@Logger(name="source") |
64 |
public final class Source implements Loggable { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
65 |
private static final int BUF_SIZE = 8 * 1024; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
66 |
private static final Cache CACHE = new Cache(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
67 |
|
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
68 |
// Message digest to file name encoder |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
69 |
private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding(); |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
70 |
|
16147 | 71 |
/** |
72 |
* Descriptive name of the source as supplied by the user. Used for error |
|
73 |
* reporting to the user. For example, SyntaxError will use this to print message. |
|
74 |
* Used to implement __FILE__. Also used for SourceFile in .class for debugger usage. |
|
75 |
*/ |
|
76 |
private final String name; |
|
77 |
||
78 |
/** |
|
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
79 |
* Base path or URL of this source. Used to implement __DIR__, which can be |
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
80 |
* used to load scripts relative to the location of the current script. |
16147 | 81 |
* This will be null when it can't be computed. |
82 |
*/ |
|
83 |
private final String base; |
|
84 |
||
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
85 |
/** Source content */ |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
86 |
private final Data data; |
16147 | 87 |
|
88 |
/** Cached hash code */ |
|
89 |
private int hash; |
|
90 |
||
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
91 |
/** Base64-encoded SHA1 digest of this source object */ |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
92 |
private volatile byte[] digest; |
23767 | 93 |
|
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
94 |
/** source URL set via //@ sourceURL or //# sourceURL directive */ |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
95 |
private String explicitURL; |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
96 |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
97 |
// Do *not* make this public, ever! Trusts the URL and content. |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
98 |
private Source(final String name, final String base, final Data data) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
99 |
this.name = name; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
100 |
this.base = base; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
101 |
this.data = data; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
102 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
103 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
104 |
private static synchronized Source sourceFor(final String name, final String base, final URLData data) throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
105 |
try { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
106 |
final Source newSource = new Source(name, base, data); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
107 |
final Source existingSource = CACHE.get(newSource); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
108 |
if (existingSource != null) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
109 |
// Force any access errors |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
110 |
data.checkPermissionAndClose(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
111 |
return existingSource; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
112 |
} |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
113 |
|
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
114 |
// All sources in cache must be fully loaded |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
115 |
data.load(); |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
116 |
CACHE.put(newSource, newSource); |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
117 |
|
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
118 |
return newSource; |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
119 |
} catch (final RuntimeException e) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
120 |
final Throwable cause = e.getCause(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
121 |
if (cause instanceof IOException) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
122 |
throw (IOException) cause; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
123 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
124 |
throw e; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
125 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
126 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
127 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
128 |
private static class Cache extends WeakHashMap<Source, WeakReference<Source>> { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
129 |
public Source get(final Source key) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
130 |
final WeakReference<Source> ref = super.get(key); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
131 |
return ref == null ? null : ref.get(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
132 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
133 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
134 |
public void put(final Source key, final Source value) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
135 |
assert !(value.data instanceof RawData); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
136 |
put(key, new WeakReference<>(value)); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
137 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
138 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
139 |
|
24881 | 140 |
/* package-private */ |
141 |
DebuggerSupport.SourceInfo getSourceInfo() { |
|
142 |
return new DebuggerSupport.SourceInfo(getName(), data.hashCode(), data.url(), data.array()); |
|
143 |
} |
|
144 |
||
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
145 |
// Wrapper to manage lazy loading |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
146 |
private static interface Data { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
147 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
148 |
URL url(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
149 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
150 |
int length(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
151 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
152 |
long lastModified(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
153 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
154 |
char[] array(); |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
155 |
|
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
156 |
boolean isEvalCode(); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
157 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
158 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
159 |
private static class RawData implements Data { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
160 |
private final char[] array; |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
161 |
private final boolean evalCode; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
162 |
private int hash; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
163 |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
164 |
private RawData(final char[] array, final boolean evalCode) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
165 |
this.array = Objects.requireNonNull(array); |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
166 |
this.evalCode = evalCode; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
167 |
} |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
168 |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
169 |
private RawData(final String source, final boolean evalCode) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
170 |
this.array = Objects.requireNonNull(source).toCharArray(); |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
171 |
this.evalCode = evalCode; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
172 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
173 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
174 |
private RawData(final Reader reader) throws IOException { |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
175 |
this(readFully(reader), false); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
176 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
177 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
178 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
179 |
public int hashCode() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
180 |
int h = hash; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
181 |
if (h == 0) { |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
182 |
h = hash = Arrays.hashCode(array) ^ (evalCode? 1 : 0); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
183 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
184 |
return h; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
185 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
186 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
187 |
@Override |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
188 |
public boolean equals(final Object obj) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
189 |
if (this == obj) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
190 |
return true; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
191 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
192 |
if (obj instanceof RawData) { |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
193 |
final RawData other = (RawData)obj; |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
194 |
return Arrays.equals(array, other.array) && evalCode == other.evalCode; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
195 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
196 |
return false; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
197 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
198 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
199 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
200 |
public String toString() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
201 |
return new String(array()); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
202 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
203 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
204 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
205 |
public URL url() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
206 |
return null; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
207 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
208 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
209 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
210 |
public int length() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
211 |
return array.length; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
212 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
213 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
214 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
215 |
public long lastModified() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
216 |
return 0; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
217 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
218 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
219 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
220 |
public char[] array() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
221 |
return array; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
222 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
223 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
224 |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
225 |
@Override |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
226 |
public boolean isEvalCode() { |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
227 |
return evalCode; |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
228 |
} |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
229 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
230 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
231 |
private static class URLData implements Data { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
232 |
private final URL url; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
233 |
protected final Charset cs; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
234 |
private int hash; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
235 |
protected char[] array; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
236 |
protected int length; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
237 |
protected long lastModified; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
238 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
239 |
private URLData(final URL url, final Charset cs) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
240 |
this.url = Objects.requireNonNull(url); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
241 |
this.cs = cs; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
242 |
} |
16147 | 243 |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
244 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
245 |
public int hashCode() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
246 |
int h = hash; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
247 |
if (h == 0) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
248 |
h = hash = url.hashCode(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
249 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
250 |
return h; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
251 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
252 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
253 |
@Override |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
254 |
public boolean equals(final Object other) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
255 |
if (this == other) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
256 |
return true; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
257 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
258 |
if (!(other instanceof URLData)) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
259 |
return false; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
260 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
261 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
262 |
final URLData otherData = (URLData) other; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
263 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
264 |
if (url.equals(otherData.url)) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
265 |
// Make sure both have meta data loaded |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
266 |
try { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
267 |
if (isDeferred()) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
268 |
// Data in cache is always loaded, and we only compare to cached data. |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
269 |
assert !otherData.isDeferred(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
270 |
loadMeta(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
271 |
} else if (otherData.isDeferred()) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
272 |
otherData.loadMeta(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
273 |
} |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
274 |
} catch (final IOException e) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
275 |
throw new RuntimeException(e); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
276 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
277 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
278 |
// Compare meta data |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
279 |
return this.length == otherData.length && this.lastModified == otherData.lastModified; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
280 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
281 |
return false; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
282 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
283 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
284 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
285 |
public String toString() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
286 |
return new String(array()); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
287 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
288 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
289 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
290 |
public URL url() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
291 |
return url; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
292 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
293 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
294 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
295 |
public int length() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
296 |
return length; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
297 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
298 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
299 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
300 |
public long lastModified() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
301 |
return lastModified; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
302 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
303 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
304 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
305 |
public char[] array() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
306 |
assert !isDeferred(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
307 |
return array; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
308 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
309 |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
310 |
@Override |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
311 |
public boolean isEvalCode() { |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
312 |
return false; |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
313 |
} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
314 |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
315 |
boolean isDeferred() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
316 |
return array == null; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
317 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
318 |
|
25250
b5a4e0ac31d1
8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents:
25240
diff
changeset
|
319 |
@SuppressWarnings("try") |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
320 |
protected void checkPermissionAndClose() throws IOException { |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
321 |
try (InputStream in = url.openStream()) { |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
322 |
// empty |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
323 |
} |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
324 |
debug("permission checked for ", url); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
325 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
326 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
327 |
protected void load() throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
328 |
if (array == null) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
329 |
final URLConnection c = url.openConnection(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
330 |
try (InputStream in = c.getInputStream()) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
331 |
array = cs == null ? readFully(in) : readFully(in, cs); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
332 |
length = array.length; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
333 |
lastModified = c.getLastModified(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
334 |
debug("loaded content for ", url); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
335 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
336 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
337 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
338 |
|
47277
69c3639a49a6
8188023: Avoid -source and -target javac options in nashorn ant compilation
sundar
parents:
47216
diff
changeset
|
339 |
@SuppressWarnings("try") |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
340 |
protected void loadMeta() throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
341 |
if (length == 0 && lastModified == 0) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
342 |
final URLConnection c = url.openConnection(); |
45725 | 343 |
try (InputStream in = c.getInputStream()) { |
344 |
length = c.getContentLength(); |
|
345 |
lastModified = c.getLastModified(); |
|
346 |
debug("loaded metadata for ", url); |
|
347 |
} |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
348 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
349 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
350 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
351 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
352 |
private static class FileData extends URLData { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
353 |
private final File file; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
354 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
355 |
private FileData(final File file, final Charset cs) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
356 |
super(getURLFromFile(file), cs); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
357 |
this.file = file; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
358 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
359 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
360 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
361 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
362 |
protected void checkPermissionAndClose() throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
363 |
if (!file.canRead()) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
364 |
throw new FileNotFoundException(file + " (Permission Denied)"); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
365 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
366 |
debug("permission checked for ", file); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
367 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
368 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
369 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
370 |
protected void loadMeta() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
371 |
if (length == 0 && lastModified == 0) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
372 |
length = (int) file.length(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
373 |
lastModified = file.lastModified(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
374 |
debug("loaded metadata for ", file); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
375 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
376 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
377 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
378 |
@Override |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
379 |
protected void load() throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
380 |
if (array == null) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
381 |
array = cs == null ? readFully(file) : readFully(file, cs); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
382 |
length = array.length; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
383 |
lastModified = file.lastModified(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
384 |
debug("loaded content for ", file); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
385 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
386 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
387 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
388 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
389 |
private static void debug(final Object... msg) { |
24769 | 390 |
final DebugLogger logger = getLoggerStatic(); |
391 |
if (logger != null) { |
|
392 |
logger.info(msg); |
|
393 |
} |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
394 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
395 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
396 |
private char[] data() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
397 |
return data.array(); |
16147 | 398 |
} |
399 |
||
400 |
/** |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
401 |
* Returns a Source instance |
16147 | 402 |
* |
403 |
* @param name source name |
|
404 |
* @param content contents as char array |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
405 |
* @param isEval does this represent code from 'eval' call? |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
406 |
* @return source instance |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
407 |
*/ |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
408 |
public static Source sourceFor(final String name, final char[] content, final boolean isEval) { |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
409 |
return new Source(name, baseName(name), new RawData(content, isEval)); |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
410 |
} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
411 |
|
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
412 |
/** |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
413 |
* Returns a Source instance |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
414 |
* |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
415 |
* @param name source name |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
416 |
* @param content contents as char array |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
417 |
* |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
418 |
* @return source instance |
16147 | 419 |
*/ |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
420 |
public static Source sourceFor(final String name, final char[] content) { |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
421 |
return sourceFor(name, content, false); |
16147 | 422 |
} |
423 |
||
424 |
/** |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
425 |
* Returns a Source instance |
16147 | 426 |
* |
427 |
* @param name source name |
|
428 |
* @param content contents as string |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
429 |
* @param isEval does this represent code from 'eval' call? |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
430 |
* @return source instance |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
431 |
*/ |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
432 |
public static Source sourceFor(final String name, final String content, final boolean isEval) { |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
433 |
return new Source(name, baseName(name), new RawData(content, isEval)); |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
434 |
} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
435 |
|
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
436 |
/** |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
437 |
* Returns a Source instance |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
438 |
* |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
439 |
* @param name source name |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
440 |
* @param content contents as string |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
441 |
* @return source instance |
16147 | 442 |
*/ |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
443 |
public static Source sourceFor(final String name, final String content) { |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
444 |
return sourceFor(name, content, false); |
16147 | 445 |
} |
446 |
||
447 |
/** |
|
448 |
* Constructor |
|
449 |
* |
|
450 |
* @param name source name |
|
451 |
* @param url url from which source can be loaded |
|
452 |
* |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
453 |
* @return source instance |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
454 |
* |
16147 | 455 |
* @throws IOException if source cannot be loaded |
456 |
*/ |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
457 |
public static Source sourceFor(final String name, final URL url) throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
458 |
return sourceFor(name, url, null); |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
459 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
460 |
|
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
461 |
/** |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
462 |
* Constructor |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
463 |
* |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
464 |
* @param name source name |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
465 |
* @param url url from which source can be loaded |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
466 |
* @param cs Charset used to convert bytes to chars |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
467 |
* |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
468 |
* @return source instance |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
469 |
* |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
470 |
* @throws IOException if source cannot be loaded |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
471 |
*/ |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
472 |
public static Source sourceFor(final String name, final URL url, final Charset cs) throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
473 |
return sourceFor(name, baseURL(url), new URLData(url, cs)); |
16147 | 474 |
} |
475 |
||
476 |
/** |
|
477 |
* Constructor |
|
478 |
* |
|
479 |
* @param name source name |
|
480 |
* @param file file from which source can be loaded |
|
481 |
* |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
482 |
* @return source instance |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
483 |
* |
16147 | 484 |
* @throws IOException if source cannot be loaded |
485 |
*/ |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
486 |
public static Source sourceFor(final String name, final File file) throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
487 |
return sourceFor(name, file, null); |
16147 | 488 |
} |
489 |
||
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
490 |
/** |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
491 |
* Constructor |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
492 |
* |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
493 |
* @param name source name |
29407 | 494 |
* @param path path from which source can be loaded |
495 |
* |
|
496 |
* @return source instance |
|
497 |
* |
|
498 |
* @throws IOException if source cannot be loaded |
|
499 |
*/ |
|
500 |
public static Source sourceFor(final String name, final Path path) throws IOException { |
|
501 |
File file = null; |
|
502 |
try { |
|
503 |
file = path.toFile(); |
|
504 |
} catch (final UnsupportedOperationException uoe) { |
|
505 |
} |
|
506 |
||
507 |
if (file != null) { |
|
508 |
return sourceFor(name, file); |
|
509 |
} else { |
|
510 |
return sourceFor(name, Files.newBufferedReader(path)); |
|
511 |
} |
|
512 |
} |
|
513 |
||
514 |
/** |
|
515 |
* Constructor |
|
516 |
* |
|
517 |
* @param name source name |
|
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
518 |
* @param file file from which source can be loaded |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
519 |
* @param cs Charset used to convert bytes to chars |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
520 |
* |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
521 |
* @return source instance |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
522 |
* |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
523 |
* @throws IOException if source cannot be loaded |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
524 |
*/ |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
525 |
public static Source sourceFor(final String name, final File file, final Charset cs) throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
526 |
final File absFile = file.getAbsoluteFile(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
527 |
return sourceFor(name, dirName(absFile, null), new FileData(file, cs)); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
528 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
529 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
530 |
/** |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
531 |
* Returns an instance |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
532 |
* |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
533 |
* @param name source name |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
534 |
* @param reader reader from which source can be loaded |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
535 |
* |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
536 |
* @return source instance |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
537 |
* |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
538 |
* @throws IOException if source cannot be loaded |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
539 |
*/ |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
540 |
public static Source sourceFor(final String name, final Reader reader) throws IOException { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
541 |
// Extract URL from URLReader to defer loading and reuse cached data if available. |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
542 |
if (reader instanceof URLReader) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
543 |
final URLReader urlReader = (URLReader) reader; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
544 |
return sourceFor(name, urlReader.getURL(), urlReader.getCharset()); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
545 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
546 |
return new Source(name, baseName(name), new RawData(reader)); |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
547 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
548 |
|
16147 | 549 |
@Override |
550 |
public boolean equals(final Object obj) { |
|
551 |
if (this == obj) { |
|
552 |
return true; |
|
553 |
} |
|
554 |
if (!(obj instanceof Source)) { |
|
555 |
return false; |
|
556 |
} |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
557 |
final Source other = (Source) obj; |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
558 |
return Objects.equals(name, other.name) && data.equals(other.data); |
16147 | 559 |
} |
560 |
||
561 |
@Override |
|
562 |
public int hashCode() { |
|
563 |
int h = hash; |
|
564 |
if (h == 0) { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
565 |
h = hash = data.hashCode() ^ Objects.hashCode(name); |
16147 | 566 |
} |
567 |
return h; |
|
568 |
} |
|
569 |
||
570 |
/** |
|
571 |
* Fetch source content. |
|
572 |
* @return Source content. |
|
573 |
*/ |
|
574 |
public String getString() { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
575 |
return data.toString(); |
16147 | 576 |
} |
577 |
||
578 |
/** |
|
579 |
* Get the user supplied name of this script. |
|
580 |
* @return User supplied source name. |
|
581 |
*/ |
|
582 |
public String getName() { |
|
583 |
return name; |
|
584 |
} |
|
585 |
||
586 |
/** |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
587 |
* Get the last modified time of this script. |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
588 |
* @return Last modified time. |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
589 |
*/ |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
590 |
public long getLastModified() { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
591 |
return data.lastModified(); |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
592 |
} |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
593 |
|
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
594 |
/** |
16147 | 595 |
* Get the "directory" part of the file or "base" of the URL. |
596 |
* @return base of file or URL. |
|
597 |
*/ |
|
598 |
public String getBase() { |
|
599 |
return base; |
|
600 |
} |
|
601 |
||
602 |
/** |
|
603 |
* Fetch a portion of source content. |
|
604 |
* @param start start index in source |
|
605 |
* @param len length of portion |
|
606 |
* @return Source content portion. |
|
607 |
*/ |
|
608 |
public String getString(final int start, final int len) { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
609 |
return new String(data(), start, len); |
16147 | 610 |
} |
611 |
||
612 |
/** |
|
613 |
* Fetch a portion of source content associated with a token. |
|
614 |
* @param token Token descriptor. |
|
615 |
* @return Source content portion. |
|
616 |
*/ |
|
617 |
public String getString(final long token) { |
|
618 |
final int start = Token.descPosition(token); |
|
619 |
final int len = Token.descLength(token); |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
620 |
return new String(data(), start, len); |
16147 | 621 |
} |
622 |
||
623 |
/** |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
624 |
* Returns the source URL of this script Source. Can be null if Source |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
625 |
* was created from a String or a char[]. |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
626 |
* |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
627 |
* @return URL source or null |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
628 |
*/ |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
629 |
public URL getURL() { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
630 |
return data.url(); |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
631 |
} |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
632 |
|
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
633 |
/** |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
634 |
* Get explicit source URL. |
29407 | 635 |
* @return URL set via sourceURL directive |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
636 |
*/ |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
637 |
public String getExplicitURL() { |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
638 |
return explicitURL; |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
639 |
} |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
640 |
|
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
641 |
/** |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
642 |
* Set explicit source URL. |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
643 |
* @param explicitURL URL set via sourceURL directive |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
644 |
*/ |
26067
b32ccc3a76c9
8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents:
26055
diff
changeset
|
645 |
public void setExplicitURL(final String explicitURL) { |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
646 |
this.explicitURL = explicitURL; |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
647 |
} |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
648 |
|
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25255
diff
changeset
|
649 |
/** |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
650 |
* Returns whether this source was submitted via 'eval' call or not. |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
651 |
* |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
652 |
* @return true if this source represents code submitted via 'eval' |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
653 |
*/ |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
654 |
public boolean isEvalCode() { |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
655 |
return data.isEvalCode(); |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
656 |
} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
657 |
|
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
658 |
/** |
16147 | 659 |
* Find the beginning of the line containing position. |
660 |
* @param position Index to offending token. |
|
661 |
* @return Index of first character of line. |
|
662 |
*/ |
|
663 |
private int findBOLN(final int position) { |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
664 |
final char[] d = data(); |
16147 | 665 |
for (int i = position - 1; i > 0; i--) { |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
666 |
final char ch = d[i]; |
16147 | 667 |
|
668 |
if (ch == '\n' || ch == '\r') { |
|
669 |
return i + 1; |
|
670 |
} |
|
671 |
} |
|
672 |
||
673 |
return 0; |
|
674 |
} |
|
675 |
||
676 |
/** |
|
677 |
* Find the end of the line containing position. |
|
678 |
* @param position Index to offending token. |
|
679 |
* @return Index of last character of line. |
|
680 |
*/ |
|
681 |
private int findEOLN(final int position) { |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
682 |
final char[] d = data(); |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
683 |
final int length = d.length; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
684 |
for (int i = position; i < length; i++) { |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
685 |
final char ch = d[i]; |
16147 | 686 |
|
687 |
if (ch == '\n' || ch == '\r') { |
|
688 |
return i - 1; |
|
689 |
} |
|
690 |
} |
|
691 |
||
692 |
return length - 1; |
|
693 |
} |
|
694 |
||
695 |
/** |
|
696 |
* Return line number of character position. |
|
20559
9244eb6d195b
8025515: Performance issues with Source.getLine()
hannesw
parents:
20210
diff
changeset
|
697 |
* |
9244eb6d195b
8025515: Performance issues with Source.getLine()
hannesw
parents:
20210
diff
changeset
|
698 |
* <p>This method can be expensive for large sources as it iterates through |
9244eb6d195b
8025515: Performance issues with Source.getLine()
hannesw
parents:
20210
diff
changeset
|
699 |
* all characters up to {@code position}.</p> |
9244eb6d195b
8025515: Performance issues with Source.getLine()
hannesw
parents:
20210
diff
changeset
|
700 |
* |
16147 | 701 |
* @param position Position of character in source content. |
702 |
* @return Line number. |
|
703 |
*/ |
|
704 |
public int getLine(final int position) { |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
705 |
final char[] d = data(); |
16147 | 706 |
// Line count starts at 1. |
707 |
int line = 1; |
|
708 |
||
709 |
for (int i = 0; i < position; i++) { |
|
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24881
diff
changeset
|
710 |
final char ch = d[i]; |
16147 | 711 |
// Works for both \n and \r\n. |
712 |
if (ch == '\n') { |
|
713 |
line++; |
|
714 |
} |
|
715 |
} |
|
716 |
||
717 |
return line; |
|
718 |
} |
|
719 |
||
720 |
/** |
|
721 |
* Return column number of character position. |
|
722 |
* @param position Position of character in source content. |
|
723 |
* @return Column number. |
|
724 |
*/ |
|
725 |
public int getColumn(final int position) { |
|
726 |
// TODO - column needs to account for tabs. |
|
727 |
return position - findBOLN(position); |
|
728 |
} |
|
729 |
||
730 |
/** |
|
731 |
* Return line text including character position. |
|
732 |
* @param position Position of character in source content. |
|
733 |
* @return Line text. |
|
734 |
*/ |
|
735 |
public String getSourceLine(final int position) { |
|
736 |
// Find end of previous line. |
|
737 |
final int first = findBOLN(position); |
|
738 |
// Find end of this line. |
|
739 |
final int last = findEOLN(position); |
|
740 |
||
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
741 |
return new String(data(), first, last - first + 1); |
16147 | 742 |
} |
743 |
||
744 |
/** |
|
26249
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
745 |
* Get the content of this source as a char array. Note that the underlying array is returned instead of a |
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
746 |
* clone; modifying the char array will cause modification to the source; this should not be done. While |
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
747 |
* there is an apparent danger that we allow unfettered access to an underlying mutable array, the |
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
748 |
* {@code Source} class is in a restricted {@code jdk.nashorn.internal.*} package and as such it is |
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
749 |
* inaccessible by external actors in an environment with a security manager. Returning a clone would be |
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
750 |
* detrimental to performance. |
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
751 |
* @return content the content of this source as a char array |
16147 | 752 |
*/ |
753 |
public char[] getContent() { |
|
26249
5fbbd38ebc5b
8056052: Source.getContent() does excess Object.clone()
attila
parents:
26068
diff
changeset
|
754 |
return data(); |
16147 | 755 |
} |
756 |
||
757 |
/** |
|
758 |
* Get the length in chars for this source |
|
759 |
* @return length |
|
760 |
*/ |
|
761 |
public int getLength() { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
762 |
return data.length(); |
16147 | 763 |
} |
764 |
||
765 |
/** |
|
766 |
* Read all of the source until end of file. Return it as char array |
|
767 |
* |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
768 |
* @param reader reader opened to source stream |
16147 | 769 |
* @return source as content |
770 |
* @throws IOException if source could not be read |
|
771 |
*/ |
|
772 |
public static char[] readFully(final Reader reader) throws IOException { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
773 |
final char[] arr = new char[BUF_SIZE]; |
16147 | 774 |
final StringBuilder sb = new StringBuilder(); |
775 |
||
776 |
try { |
|
777 |
int numChars; |
|
778 |
while ((numChars = reader.read(arr, 0, arr.length)) > 0) { |
|
779 |
sb.append(arr, 0, numChars); |
|
780 |
} |
|
781 |
} finally { |
|
782 |
reader.close(); |
|
783 |
} |
|
784 |
||
785 |
return sb.toString().toCharArray(); |
|
786 |
} |
|
787 |
||
788 |
/** |
|
789 |
* Read all of the source until end of file. Return it as char array |
|
790 |
* |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
791 |
* @param file source file |
16147 | 792 |
* @return source as content |
793 |
* @throws IOException if source could not be read |
|
794 |
*/ |
|
795 |
public static char[] readFully(final File file) throws IOException { |
|
796 |
if (!file.isFile()) { |
|
797 |
throw new IOException(file + " is not a file"); //TODO localize? |
|
798 |
} |
|
799 |
return byteToCharArray(Files.readAllBytes(file.toPath())); |
|
800 |
} |
|
801 |
||
802 |
/** |
|
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
803 |
* Read all of the source until end of file. Return it as char array |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
804 |
* |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
805 |
* @param file source file |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
806 |
* @param cs Charset used to convert bytes to chars |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
807 |
* @return source as content |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
808 |
* @throws IOException if source could not be read |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
809 |
*/ |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
810 |
public static char[] readFully(final File file, final Charset cs) throws IOException { |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
811 |
if (!file.isFile()) { |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
812 |
throw new IOException(file + " is not a file"); //TODO localize? |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
813 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
814 |
|
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
815 |
final byte[] buf = Files.readAllBytes(file.toPath()); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
816 |
return (cs != null) ? new String(buf, cs).toCharArray() : byteToCharArray(buf); |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
817 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
818 |
|
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
819 |
/** |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
820 |
* Read all of the source until end of stream from the given URL. Return it as char array |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
821 |
* |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
822 |
* @param url URL to read content from |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
823 |
* @return source as content |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
824 |
* @throws IOException if source could not be read |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
825 |
*/ |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
826 |
public static char[] readFully(final URL url) throws IOException { |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
827 |
return readFully(url.openStream()); |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
828 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
829 |
|
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
830 |
/** |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
831 |
* Read all of the source until end of file. Return it as char array |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
832 |
* |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
833 |
* @param url URL to read content from |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
834 |
* @param cs Charset used to convert bytes to chars |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
835 |
* @return source as content |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
836 |
* @throws IOException if source could not be read |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
837 |
*/ |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
838 |
public static char[] readFully(final URL url, final Charset cs) throws IOException { |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
839 |
return readFully(url.openStream(), cs); |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
840 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
841 |
|
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
842 |
/** |
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
843 |
* Get a Base64-encoded SHA1 digest for this source. |
23767 | 844 |
* |
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
845 |
* @return a Base64-encoded SHA1 digest for this source |
23767 | 846 |
*/ |
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
847 |
public String getDigest() { |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
848 |
return new String(getDigestBytes(), StandardCharsets.US_ASCII); |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
849 |
} |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
850 |
|
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
851 |
private byte[] getDigestBytes() { |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
852 |
byte[] ldigest = digest; |
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
853 |
if (ldigest == null) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
854 |
final char[] content = data(); |
23767 | 855 |
final byte[] bytes = new byte[content.length * 2]; |
856 |
||
857 |
for (int i = 0; i < content.length; i++) { |
|
858 |
bytes[i * 2] = (byte) (content[i] & 0x00ff); |
|
859 |
bytes[i * 2 + 1] = (byte) ((content[i] & 0xff00) >> 8); |
|
860 |
} |
|
861 |
||
862 |
try { |
|
863 |
final MessageDigest md = MessageDigest.getInstance("SHA-1"); |
|
864 |
if (name != null) { |
|
865 |
md.update(name.getBytes(StandardCharsets.UTF_8)); |
|
866 |
} |
|
867 |
if (base != null) { |
|
868 |
md.update(base.getBytes(StandardCharsets.UTF_8)); |
|
869 |
} |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
870 |
if (getURL() != null) { |
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
871 |
md.update(getURL().toString().getBytes(StandardCharsets.UTF_8)); |
23767 | 872 |
} |
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
873 |
digest = ldigest = BASE64.encode(md.digest(bytes)); |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
874 |
} catch (final NoSuchAlgorithmException e) { |
23767 | 875 |
throw new RuntimeException(e); |
876 |
} |
|
877 |
} |
|
25255
cf56cdc2c663
8049225: Source class exposes public mutable array
attila
parents:
25250
diff
changeset
|
878 |
return ldigest; |
23767 | 879 |
} |
880 |
||
881 |
/** |
|
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
882 |
* Returns the base directory or URL for the given URL. Used to implement __DIR__. |
16147 | 883 |
* @param url a URL |
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
884 |
* @return base path or URL, or null if argument is not a hierarchical URL |
16147 | 885 |
*/ |
886 |
public static String baseURL(final URL url) { |
|
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
887 |
try { |
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
888 |
final URI uri = url.toURI(); |
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
889 |
|
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
890 |
if (uri.getScheme().equals("file")) { |
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
891 |
final Path path = Paths.get(uri); |
16147 | 892 |
final Path parent = path.getParent(); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
893 |
return (parent != null) ? (parent + File.separator) : null; |
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
894 |
} |
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
895 |
if (uri.isOpaque() || uri.getPath() == null || uri.getPath().isEmpty()) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
896 |
return null; |
16147 | 897 |
} |
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
898 |
return uri.resolve("").toString(); |
16147 | 899 |
|
39351
a049c96353ae
8160435: Source.baseURL is slow for URLs with unregistered protocol
hannesw
parents:
36517
diff
changeset
|
900 |
} catch (final SecurityException | URISyntaxException | IOError e) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
901 |
return null; |
16147 | 902 |
} |
903 |
} |
|
904 |
||
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
905 |
private static String dirName(final File file, final String DEFAULT_BASE_NAME) { |
16147 | 906 |
final String res = file.getParent(); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
907 |
return (res != null) ? (res + File.separator) : DEFAULT_BASE_NAME; |
16147 | 908 |
} |
909 |
||
910 |
// fake directory like name |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
911 |
private static String baseName(final String name) { |
16147 | 912 |
int idx = name.lastIndexOf('/'); |
913 |
if (idx == -1) { |
|
914 |
idx = name.lastIndexOf('\\'); |
|
915 |
} |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
916 |
return (idx != -1) ? name.substring(0, idx + 1) : null; |
16147 | 917 |
} |
918 |
||
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
919 |
private static char[] readFully(final InputStream is, final Charset cs) throws IOException { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
920 |
return (cs != null) ? new String(readBytes(is), cs).toCharArray() : readFully(is); |
18337
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
921 |
} |
effcb00fcf58
8008915: URLReader constructor should allow specifying encoding
sundar
parents:
16241
diff
changeset
|
922 |
|
36517 | 923 |
public static char[] readFully(final InputStream is) throws IOException { |
16147 | 924 |
return byteToCharArray(readBytes(is)); |
925 |
} |
|
926 |
||
927 |
private static char[] byteToCharArray(final byte[] bytes) { |
|
928 |
Charset cs = StandardCharsets.UTF_8; |
|
929 |
int start = 0; |
|
930 |
// BOM detection. |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
931 |
if (bytes.length > 1 && bytes[0] == (byte) 0xFE && bytes[1] == (byte) 0xFF) { |
16147 | 932 |
start = 2; |
933 |
cs = StandardCharsets.UTF_16BE; |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
934 |
} else if (bytes.length > 1 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE) { |
30974 | 935 |
if (bytes.length > 3 && bytes[2] == 0 && bytes[3] == 0) { |
936 |
start = 4; |
|
937 |
cs = Charset.forName("UTF-32LE"); |
|
938 |
} else { |
|
939 |
start = 2; |
|
940 |
cs = StandardCharsets.UTF_16LE; |
|
941 |
} |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
942 |
} else if (bytes.length > 2 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) { |
16147 | 943 |
start = 3; |
944 |
cs = StandardCharsets.UTF_8; |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
945 |
} else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF) { |
16147 | 946 |
start = 4; |
947 |
cs = Charset.forName("UTF-32BE"); |
|
948 |
} |
|
949 |
||
950 |
return new String(bytes, start, bytes.length - start, cs).toCharArray(); |
|
951 |
} |
|
952 |
||
953 |
static byte[] readBytes(final InputStream is) throws IOException { |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
954 |
final byte[] arr = new byte[BUF_SIZE]; |
16147 | 955 |
try { |
956 |
try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) { |
|
957 |
int numBytes; |
|
958 |
while ((numBytes = is.read(arr, 0, arr.length)) > 0) { |
|
959 |
buf.write(arr, 0, numBytes); |
|
960 |
} |
|
961 |
return buf.toByteArray(); |
|
962 |
} |
|
963 |
} finally { |
|
964 |
is.close(); |
|
965 |
} |
|
966 |
} |
|
967 |
||
968 |
@Override |
|
969 |
public String toString() { |
|
970 |
return getName(); |
|
971 |
} |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
972 |
|
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
973 |
private static URL getURLFromFile(final File file) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
974 |
try { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
975 |
return file.toURI().toURL(); |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
976 |
} catch (final SecurityException | MalformedURLException ignored) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
977 |
return null; |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
978 |
} |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16151
diff
changeset
|
979 |
} |
24769 | 980 |
|
981 |
private static DebugLogger getLoggerStatic() { |
|
982 |
final Context context = Context.getContextTrustedOrNull(); |
|
983 |
return context == null ? null : context.getLogger(Source.class); |
|
984 |
} |
|
985 |
||
986 |
@Override |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24769
diff
changeset
|
987 |
public DebugLogger initLogger(final Context context) { |
24769 | 988 |
return context.getLogger(this.getClass()); |
989 |
} |
|
990 |
||
991 |
@Override |
|
992 |
public DebugLogger getLogger() { |
|
993 |
return initLogger(Context.getContextTrusted()); |
|
994 |
} |
|
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
995 |
|
31546
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
996 |
private File dumpFile(final File dirFile) { |
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
997 |
final URL u = getURL(); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
998 |
final StringBuilder buf = new StringBuilder(); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
999 |
// make it unique by prefixing current date & time |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1000 |
buf.append(LocalDateTime.now().toString()); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1001 |
buf.append('_'); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1002 |
if (u != null) { |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1003 |
// make it a safe file name |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1004 |
buf.append(u.toString() |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1005 |
.replace('/', '_') |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1006 |
.replace('\\', '_')); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1007 |
} else { |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1008 |
buf.append(getName()); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1009 |
} |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1010 |
|
31546
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1011 |
return new File(dirFile, buf.toString()); |
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1012 |
} |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1013 |
|
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1014 |
void dump(final String dir) { |
31546
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1015 |
final File dirFile = new File(dir); |
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1016 |
final File file = dumpFile(dirFile); |
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1017 |
if (!dirFile.exists() && !dirFile.mkdirs()) { |
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1018 |
debug("Skipping source dump for " + name); |
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1019 |
return; |
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1020 |
} |
c1ae3f297a28
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents:
30974
diff
changeset
|
1021 |
|
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1022 |
try (final FileOutputStream fos = new FileOutputStream(file)) { |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1023 |
final PrintWriter pw = new PrintWriter(fos); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1024 |
pw.print(data.toString()); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1025 |
pw.flush(); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1026 |
} catch (final IOException ioExp) { |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1027 |
debug("Skipping source dump for " + |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1028 |
name + |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1029 |
": " + |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1030 |
ECMAErrors.getMessage( |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1031 |
"io.error.cant.write", |
31549
b627094c5649
8130734: Apply transformations found by netbeans Refactor->Inspect and transform menu
sundar
parents:
31546
diff
changeset
|
1032 |
dir + |
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1033 |
" : " + ioExp.toString())); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1034 |
} |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
29407
diff
changeset
|
1035 |
} |
16147 | 1036 |
} |