Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-aarch32-jdk8u
Path: blob/jdk8u272-b10-aarch32-20201026/jaxp/src/com/sun/xml/internal/stream/XMLEntityStorage.java
83408 views
1
/*
2
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.xml.internal.stream;
27
28
import com.sun.org.apache.xerces.internal.impl.Constants;
29
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
30
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
31
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
32
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
33
import com.sun.org.apache.xerces.internal.util.URI;
34
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
35
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
36
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
37
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
38
import java.util.Collections;
39
import java.util.Enumeration;
40
import java.util.HashMap;
41
import java.util.Map;
42
43
/**
44
*
45
* @author K.Venugopal SUN Microsystems
46
* @author Neeraj Bajaj SUN Microsystems
47
* @author Andy Clark, IBM
48
*
49
*/
50
public class XMLEntityStorage {
51
52
/** Property identifier: error reporter. */
53
protected static final String ERROR_REPORTER =
54
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
55
56
/** Feature identifier: warn on duplicate EntityDef */
57
protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
58
Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
59
60
/** warn on duplicate Entity declaration.
61
* http://apache.org/xml/features/warn-on-duplicate-entitydef
62
*/
63
protected boolean fWarnDuplicateEntityDef;
64
65
/** Entities. */
66
protected Map<String, Entity> fEntities = new HashMap<>();
67
68
protected Entity.ScannedEntity fCurrentEntity ;
69
70
private XMLEntityManager fEntityManager;
71
/**
72
* Error reporter. This property identifier is:
73
* http://apache.org/xml/properties/internal/error-reporter
74
*/
75
protected XMLErrorReporter fErrorReporter;
76
protected PropertyManager fPropertyManager ;
77
78
/* To keep track whether an entity is declared in external or internal subset*/
79
protected boolean fInExternalSubset = false;
80
81
/** Creates a new instance of XMLEntityStorage */
82
public XMLEntityStorage(PropertyManager propertyManager) {
83
fPropertyManager = propertyManager ;
84
}
85
86
/** Creates a new instance of XMLEntityStorage */
87
/*public XMLEntityStorage(Entity.ScannedEntity currentEntity) {
88
fCurrentEntity = currentEntity ;*/
89
public XMLEntityStorage(XMLEntityManager entityManager) {
90
fEntityManager = entityManager;
91
}
92
93
public void reset(PropertyManager propertyManager){
94
95
fErrorReporter = (XMLErrorReporter)propertyManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY);
96
fEntities.clear();
97
fCurrentEntity = null;
98
99
}
100
101
public void reset(){
102
fEntities.clear();
103
fCurrentEntity = null;
104
}
105
/**
106
* Resets the component. The component can query the component manager
107
* about any features and properties that affect the operation of the
108
* component.
109
*
110
* @param componentManager The component manager.
111
*
112
* @throws SAXException Thrown by component on initialization error.
113
* For example, if a feature or property is
114
* required for the operation of the component, the
115
* component manager may throw a
116
* SAXNotRecognizedException or a
117
* SAXNotSupportedException.
118
*/
119
public void reset(XMLComponentManager componentManager)
120
throws XMLConfigurationException {
121
122
123
// xerces features
124
125
fWarnDuplicateEntityDef = componentManager.getFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);
126
127
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
128
129
fEntities.clear();
130
fCurrentEntity = null;
131
132
} // reset(XMLComponentManager)
133
134
/**
135
* Returns entity declaration.
136
*
137
* @param name The name of the entity.
138
*
139
* @see SymbolTable
140
*/
141
public Entity getEntity(String name) {
142
return fEntities.get(name);
143
} // getEntity(String)
144
145
public boolean hasEntities() {
146
return (fEntities!=null);
147
} // getEntity(String)
148
149
public int getEntitySize() {
150
return fEntities.size();
151
} // getEntity(String)
152
153
public Enumeration getEntityKeys() {
154
return Collections.enumeration(fEntities.keySet());
155
}
156
/**
157
* Adds an internal entity declaration.
158
* <p>
159
* <strong>Note:</strong> This method ignores subsequent entity
160
* declarations.
161
* <p>
162
* <strong>Note:</strong> The name should be a unique symbol. The
163
* SymbolTable can be used for this purpose.
164
*
165
* @param name The name of the entity.
166
* @param text The text of the entity.
167
*
168
* @see SymbolTable
169
*/
170
public void addInternalEntity(String name, String text) {
171
if (!fEntities.containsKey(name)) {
172
Entity entity = new Entity.InternalEntity(name, text, fInExternalSubset);
173
fEntities.put(name, entity);
174
}
175
else{
176
if(fWarnDuplicateEntityDef){
177
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
178
"MSG_DUPLICATE_ENTITY_DEFINITION",
179
new Object[]{ name },
180
XMLErrorReporter.SEVERITY_WARNING );
181
}
182
}
183
} // addInternalEntity(String,String)
184
185
/**
186
* Adds an external entity declaration.
187
* <p>
188
* <strong>Note:</strong> This method ignores subsequent entity
189
* declarations.
190
* <p>
191
* <strong>Note:</strong> The name should be a unique symbol. The
192
* SymbolTable can be used for this purpose.
193
*
194
* @param name The name of the entity.
195
* @param publicId The public identifier of the entity.
196
* @param literalSystemId The system identifier of the entity.
197
* @param baseSystemId The base system identifier of the entity.
198
* This is the system identifier of the entity
199
* where <em>the entity being added</em> and
200
* is used to expand the system identifier when
201
* the system identifier is a relative URI.
202
* When null the system identifier of the first
203
* external entity on the stack is used instead.
204
*
205
* @see SymbolTable
206
*/
207
public void addExternalEntity(String name,
208
String publicId, String literalSystemId,
209
String baseSystemId) {
210
if (!fEntities.containsKey(name)) {
211
if (baseSystemId == null) {
212
// search for the first external entity on the stack
213
//xxx commenting the 'size' variable..
214
/**
215
* int size = fEntityStack.size();
216
* if (size == 0 && fCurrentEntity != null && fCurrentEntity.entityLocation != null) {
217
* baseSystemId = fCurrentEntity.entityLocation.getExpandedSystemId();
218
* }
219
*/
220
221
//xxx we need to have information about the current entity.
222
if (fCurrentEntity != null && fCurrentEntity.entityLocation != null) {
223
baseSystemId = fCurrentEntity.entityLocation.getExpandedSystemId();
224
}
225
/**
226
* for (int i = size - 1; i >= 0 ; i--) {
227
* ScannedEntity externalEntity =
228
* (ScannedEntity)fEntityStack.elementAt(i);
229
* if (externalEntity.entityLocation != null && externalEntity.entityLocation.getExpandedSystemId() != null) {
230
* baseSystemId = externalEntity.entityLocation.getExpandedSystemId();
231
* break;
232
* }
233
* }
234
*/
235
}
236
237
fCurrentEntity = fEntityManager.getCurrentEntity();
238
Entity entity = new Entity.ExternalEntity(name,
239
new XMLResourceIdentifierImpl(publicId, literalSystemId,
240
baseSystemId, expandSystemId(literalSystemId, baseSystemId)),
241
null, fInExternalSubset);
242
//TODO :: Forced to pass true above remove it.
243
//(fCurrentEntity == null) ? fasle : fCurrentEntity.isEntityDeclInExternalSubset());
244
// null, fCurrentEntity.isEntityDeclInExternalSubset());
245
fEntities.put(name, entity);
246
}
247
else{
248
if(fWarnDuplicateEntityDef){
249
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
250
"MSG_DUPLICATE_ENTITY_DEFINITION",
251
new Object[]{ name },
252
XMLErrorReporter.SEVERITY_WARNING );
253
}
254
}
255
256
} // addExternalEntity(String,String,String,String)
257
258
/**
259
* Checks whether an entity given by name is external.
260
*
261
* @param entityName The name of the entity to check.
262
* @returns True if the entity is external, false otherwise
263
* (including when the entity is not declared).
264
*/
265
public boolean isExternalEntity(String entityName) {
266
267
Entity entity = fEntities.get(entityName);
268
if (entity == null) {
269
return false;
270
}
271
return entity.isExternal();
272
}
273
274
/**
275
* Checks whether the declaration of an entity given by name is
276
* // in the external subset.
277
*
278
* @param entityName The name of the entity to check.
279
* @returns True if the entity was declared in the external subset, false otherwise
280
* (including when the entity is not declared).
281
*/
282
public boolean isEntityDeclInExternalSubset(String entityName) {
283
284
Entity entity = fEntities.get(entityName);
285
if (entity == null) {
286
return false;
287
}
288
return entity.isEntityDeclInExternalSubset();
289
}
290
291
/**
292
* Adds an unparsed entity declaration.
293
* <p>
294
* <strong>Note:</strong> This method ignores subsequent entity
295
* declarations.
296
* <p>
297
* <strong>Note:</strong> The name should be a unique symbol. The
298
* SymbolTable can be used for this purpose.
299
*
300
* @param name The name of the entity.
301
* @param publicId The public identifier of the entity.
302
* @param systemId The system identifier of the entity.
303
* @param notation The name of the notation.
304
*
305
* @see SymbolTable
306
*/
307
public void addUnparsedEntity(String name,
308
String publicId, String systemId,
309
String baseSystemId, String notation) {
310
311
fCurrentEntity = fEntityManager.getCurrentEntity();
312
if (!fEntities.containsKey(name)) {
313
Entity entity = new Entity.ExternalEntity(name, new XMLResourceIdentifierImpl(publicId, systemId, baseSystemId, null), notation, fInExternalSubset);
314
// (fCurrentEntity == null) ? fasle : fCurrentEntity.isEntityDeclInExternalSubset());
315
// fCurrentEntity.isEntityDeclInExternalSubset());
316
fEntities.put(name, entity);
317
}
318
else{
319
if(fWarnDuplicateEntityDef){
320
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
321
"MSG_DUPLICATE_ENTITY_DEFINITION",
322
new Object[]{ name },
323
XMLErrorReporter.SEVERITY_WARNING );
324
}
325
}
326
} // addUnparsedEntity(String,String,String,String)
327
328
/**
329
* Checks whether an entity given by name is unparsed.
330
*
331
* @param entityName The name of the entity to check.
332
* @returns True if the entity is unparsed, false otherwise
333
* (including when the entity is not declared).
334
*/
335
public boolean isUnparsedEntity(String entityName) {
336
337
Entity entity = fEntities.get(entityName);
338
if (entity == null) {
339
return false;
340
}
341
return entity.isUnparsed();
342
}
343
344
/**
345
* Checks whether an entity given by name is declared.
346
*
347
* @param entityName The name of the entity to check.
348
* @returns True if the entity is declared, false otherwise.
349
*/
350
public boolean isDeclaredEntity(String entityName) {
351
352
Entity entity = fEntities.get(entityName);
353
return entity != null;
354
}
355
/**
356
* Expands a system id and returns the system id as a URI, if
357
* it can be expanded. A return value of null means that the
358
* identifier is already expanded. An exception thrown
359
* indicates a failure to expand the id.
360
*
361
* @param systemId The systemId to be expanded.
362
*
363
* @return Returns the URI string representing the expanded system
364
* identifier. A null value indicates that the given
365
* system identifier is already expanded.
366
*
367
*/
368
public static String expandSystemId(String systemId) {
369
return expandSystemId(systemId, null);
370
} // expandSystemId(String):String
371
372
// current value of the "user.dir" property
373
private static String gUserDir;
374
// escaped value of the current "user.dir" property
375
private static String gEscapedUserDir;
376
// which ASCII characters need to be escaped
377
private static boolean gNeedEscaping[] = new boolean[128];
378
// the first hex character if a character needs to be escaped
379
private static char gAfterEscaping1[] = new char[128];
380
// the second hex character if a character needs to be escaped
381
private static char gAfterEscaping2[] = new char[128];
382
private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
383
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
384
// initialize the above 3 arrays
385
static {
386
for (int i = 0; i <= 0x1f; i++) {
387
gNeedEscaping[i] = true;
388
gAfterEscaping1[i] = gHexChs[i >> 4];
389
gAfterEscaping2[i] = gHexChs[i & 0xf];
390
}
391
gNeedEscaping[0x7f] = true;
392
gAfterEscaping1[0x7f] = '7';
393
gAfterEscaping2[0x7f] = 'F';
394
char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
395
'|', '\\', '^', '~', '[', ']', '`'};
396
int len = escChs.length;
397
char ch;
398
for (int i = 0; i < len; i++) {
399
ch = escChs[i];
400
gNeedEscaping[ch] = true;
401
gAfterEscaping1[ch] = gHexChs[ch >> 4];
402
gAfterEscaping2[ch] = gHexChs[ch & 0xf];
403
}
404
}
405
// To escape the "user.dir" system property, by using %HH to represent
406
// special ASCII characters: 0x00~0x1F, 0x7F, ' ', '<', '>', '#', '%'
407
// and '"'. It's a static method, so needs to be synchronized.
408
// this method looks heavy, but since the system property isn't expected
409
// to change often, so in most cases, we only need to return the string
410
// that was escaped before.
411
// According to the URI spec, non-ASCII characters (whose value >= 128)
412
// need to be escaped too.
413
// REVISIT: don't know how to escape non-ASCII characters, especially
414
// which encoding to use. Leave them for now.
415
private static synchronized String getUserDir() {
416
// get the user.dir property
417
String userDir = "";
418
try {
419
userDir = SecuritySupport.getSystemProperty("user.dir");
420
}
421
catch (SecurityException se) {
422
}
423
424
// return empty string if property value is empty string.
425
if (userDir.length() == 0)
426
return "";
427
428
// compute the new escaped value if the new property value doesn't
429
// match the previous one
430
if (userDir.equals(gUserDir)) {
431
return gEscapedUserDir;
432
}
433
434
// record the new value as the global property value
435
gUserDir = userDir;
436
437
char separator = java.io.File.separatorChar;
438
userDir = userDir.replace(separator, '/');
439
440
int len = userDir.length(), ch;
441
StringBuffer buffer = new StringBuffer(len*3);
442
// change C:/blah to /C:/blah
443
if (len >= 2 && userDir.charAt(1) == ':') {
444
ch = Character.toUpperCase(userDir.charAt(0));
445
if (ch >= 'A' && ch <= 'Z') {
446
buffer.append('/');
447
}
448
}
449
450
// for each character in the path
451
int i = 0;
452
for (; i < len; i++) {
453
ch = userDir.charAt(i);
454
// if it's not an ASCII character, break here, and use UTF-8 encoding
455
if (ch >= 128)
456
break;
457
if (gNeedEscaping[ch]) {
458
buffer.append('%');
459
buffer.append(gAfterEscaping1[ch]);
460
buffer.append(gAfterEscaping2[ch]);
461
// record the fact that it's escaped
462
}
463
else {
464
buffer.append((char)ch);
465
}
466
}
467
468
// we saw some non-ascii character
469
if (i < len) {
470
// get UTF-8 bytes for the remaining sub-string
471
byte[] bytes = null;
472
byte b;
473
try {
474
bytes = userDir.substring(i).getBytes("UTF-8");
475
} catch (java.io.UnsupportedEncodingException e) {
476
// should never happen
477
return userDir;
478
}
479
len = bytes.length;
480
481
// for each byte
482
for (i = 0; i < len; i++) {
483
b = bytes[i];
484
// for non-ascii character: make it positive, then escape
485
if (b < 0) {
486
ch = b + 256;
487
buffer.append('%');
488
buffer.append(gHexChs[ch >> 4]);
489
buffer.append(gHexChs[ch & 0xf]);
490
}
491
else if (gNeedEscaping[b]) {
492
buffer.append('%');
493
buffer.append(gAfterEscaping1[b]);
494
buffer.append(gAfterEscaping2[b]);
495
}
496
else {
497
buffer.append((char)b);
498
}
499
}
500
}
501
502
// change blah/blah to blah/blah/
503
if (!userDir.endsWith("/"))
504
buffer.append('/');
505
506
gEscapedUserDir = buffer.toString();
507
508
return gEscapedUserDir;
509
}
510
511
/**
512
* Expands a system id and returns the system id as a URI, if
513
* it can be expanded. A return value of null means that the
514
* identifier is already expanded. An exception thrown
515
* indicates a failure to expand the id.
516
*
517
* @param systemId The systemId to be expanded.
518
*
519
* @return Returns the URI string representing the expanded system
520
* identifier. A null value indicates that the given
521
* system identifier is already expanded.
522
*
523
*/
524
public static String expandSystemId(String systemId, String baseSystemId) {
525
526
// check for bad parameters id
527
if (systemId == null || systemId.length() == 0) {
528
return systemId;
529
}
530
// if id already expanded, return
531
try {
532
new URI(systemId);
533
return systemId;
534
} catch (URI.MalformedURIException e) {
535
// continue on...
536
}
537
// normalize id
538
String id = fixURI(systemId);
539
540
// normalize base
541
URI base = null;
542
URI uri = null;
543
try {
544
if (baseSystemId == null || baseSystemId.length() == 0 ||
545
baseSystemId.equals(systemId)) {
546
String dir = getUserDir();
547
base = new URI("file", "", dir, null, null);
548
}
549
else {
550
try {
551
base = new URI(fixURI(baseSystemId));
552
}
553
catch (URI.MalformedURIException e) {
554
if (baseSystemId.indexOf(':') != -1) {
555
// for xml schemas we might have baseURI with
556
// a specified drive
557
base = new URI("file", "", fixURI(baseSystemId), null, null);
558
}
559
else {
560
String dir = getUserDir();
561
dir = dir + fixURI(baseSystemId);
562
base = new URI("file", "", dir, null, null);
563
}
564
}
565
}
566
// expand id
567
uri = new URI(base, id);
568
}
569
catch (Exception e) {
570
// let it go through
571
572
}
573
574
if (uri == null) {
575
return systemId;
576
}
577
return uri.toString();
578
579
} // expandSystemId(String,String):String
580
//
581
// Protected static methods
582
//
583
584
/**
585
* Fixes a platform dependent filename to standard URI form.
586
*
587
* @param str The string to fix.
588
*
589
* @return Returns the fixed URI string.
590
*/
591
protected static String fixURI(String str) {
592
593
// handle platform dependent strings
594
str = str.replace(java.io.File.separatorChar, '/');
595
596
// Windows fix
597
if (str.length() >= 2) {
598
char ch1 = str.charAt(1);
599
// change "C:blah" to "/C:blah"
600
if (ch1 == ':') {
601
char ch0 = Character.toUpperCase(str.charAt(0));
602
if (ch0 >= 'A' && ch0 <= 'Z') {
603
str = "/" + str;
604
}
605
}
606
// change "//blah" to "file://blah"
607
else if (ch1 == '/' && str.charAt(0) == '/') {
608
str = "file:" + str;
609
}
610
}
611
612
// done
613
return str;
614
615
} // fixURI(String):String
616
617
// indicate start of external subset
618
public void startExternalSubset() {
619
fInExternalSubset = true;
620
}
621
622
public void endExternalSubset() {
623
fInExternalSubset = false;
624
}
625
}
626
627