Skip to content

Commit 5e904e6

Browse files
authored
Merge pull request #4527 from evolvedbinary/feature/fn-serialize,use-character-maps
[Feature] fn serialize,use character maps
2 parents 518b93e + 89560a5 commit 5e904e6

26 files changed

+954
-195
lines changed

exist-core/src/main/java/org/exist/storage/serializers/EXistOutputKeys.java

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,73 +26,73 @@ public class EXistOutputKeys {
2626
/**
2727
* Parameter "item-separator" from the XQuery serialization spec 3.1
2828
*/
29-
public final static String ITEM_SEPARATOR = "item-separator";
29+
public static final String ITEM_SEPARATOR = "item-separator";
3030

31-
public final static String OUTPUT_DOCTYPE = "output-doctype";
31+
public static final String OUTPUT_DOCTYPE = "output-doctype";
3232

33-
public final static String EXPAND_XINCLUDES = "expand-xincludes";
33+
public static final String EXPAND_XINCLUDES = "expand-xincludes";
3434

35-
public final static String PROCESS_XSL_PI = "process-xsl-pi";
35+
public static final String PROCESS_XSL_PI = "process-xsl-pi";
3636

37-
public final static String HIGHLIGHT_MATCHES = "highlight-matches";
37+
public static final String HIGHLIGHT_MATCHES = "highlight-matches";
3838

39-
public final static String INDENT_SPACES = "indent-spaces";
39+
public static final String INDENT_SPACES = "indent-spaces";
4040

41-
public final static String STYLESHEET = "stylesheet";
41+
public static final String STYLESHEET = "stylesheet";
4242

43-
public final static String STYLESHEET_PARAM = "stylesheet-param";
43+
public static final String STYLESHEET_PARAM = "stylesheet-param";
4444

45-
public final static String COMPRESS_OUTPUT = "compress-output";
45+
public static final String COMPRESS_OUTPUT = "compress-output";
4646

47-
public final static String ADD_EXIST_ID = "add-exist-id";
47+
public static final String ADD_EXIST_ID = "add-exist-id";
4848

49-
public final static String XINCLUDE_PATH = "xinclude-path";
49+
public static final String XINCLUDE_PATH = "xinclude-path";
5050

5151
/**
5252
* Enforce XHTML namespace on elements with no namespace
5353
*/
54-
public final static String ENFORCE_XHTML = "enforce-xhtml";
54+
public static final String ENFORCE_XHTML = "enforce-xhtml";
5555

5656
/**
5757
* Applies to JSON serialization only: preserve namespace prefixes in JSON properties
5858
* by replacing ":" with "_", so element foo:bar becomes "foo_bar".
5959
*/
60-
public final static String JSON_OUTPUT_NS_PREFIX = "preserve-prefix";
60+
public static final String JSON_OUTPUT_NS_PREFIX = "preserve-prefix";
6161

6262
/**
6363
* Applies to JSON serialization only: sets the jsonp callback function
6464
*/
65-
public final static String JSONP = "jsonp";
65+
public static final String JSONP = "jsonp";
6666

6767
/**
6868
* JSON serialization: prefix XML attributes with a '@' when serializing
6969
* them as JSON properties
7070
*/
71-
public final static String JSON_PREFIX_ATTRIBUTES = "prefix-attributes";
71+
public static final String JSON_PREFIX_ATTRIBUTES = "prefix-attributes";
7272

7373
/**
7474
* JSON serialization: if text nodes are encountered which consist solely of whitespace then they
7575
* will be ignored by the serializer
7676
*/
77-
public final static String JSON_IGNORE_WHITESPACE_TEXT_NODES = "json-ignore-whitespace-text-nodes";
77+
public static final String JSON_IGNORE_WHITESPACE_TEXT_NODES = "json-ignore-whitespace-text-nodes";
7878

7979
/**
8080
* Defines the output method to be used for serializing nodes within json output.
8181
*/
82-
public final static String JSON_NODE_OUTPUT_METHOD = "json-node-output-method";
82+
public static final String JSON_NODE_OUTPUT_METHOD = "json-node-output-method";
8383

8484
/**
8585
* Defines the output for JSON serializing to array even if only one item.
8686
*/
87-
public final static String JSON_ARRAY_OUTPUT = "json-array-output";
87+
public static final String JSON_ARRAY_OUTPUT = "json-array-output";
8888

8989
/**
9090
* Determines whether the presence of multiple keys in a map item with the same string value
9191
* will or will not raise serialization error err:SERE0022.
9292
*/
93-
public final static String ALLOW_DUPLICATE_NAMES = "allow-duplicate-names";
93+
public static final String ALLOW_DUPLICATE_NAMES = "allow-duplicate-names";
9494

95-
public final static String HTML_VERSION = "html-version";
95+
public static final String HTML_VERSION = "html-version";
9696

9797
/**
9898
* When serializing an XDM this should be used
@@ -103,7 +103,7 @@ public class EXistOutputKeys {
103103
*
104104
* Set to "yes" to enable xdm-serialization rules, false otherwise.
105105
*/
106-
public final static String XDM_SERIALIZATION = "xdm-serialization";
106+
public static final String XDM_SERIALIZATION = "xdm-serialization";
107107

108108
/**
109109
* Enforce newline at the end of JSON and XML documents.
@@ -113,5 +113,7 @@ public class EXistOutputKeys {
113113
* exist-db and will lead to less meaningless changes in git and tools
114114
* like diff will be able to provide more meaningful information as well.
115115
*/
116-
public final static String INSERT_FINAL_NEWLINE = "insert-final-newline";
116+
public static final String INSERT_FINAL_NEWLINE = "insert-final-newline";
117+
118+
public static final String USE_CHARACTER_MAPS = "use-character-maps";
117119
}

exist-core/src/main/java/org/exist/storage/serializers/Serializer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ public abstract class Serializer implements XMLReader {
191191
protected Receiver receiver = null;
192192
protected SAXSerializer xmlout = null;
193193
protected LexicalHandler lexicalHandler = null;
194+
protected Map<Integer, String> useCharacterMaps = null;
194195
protected Subject user = null;
195196

196197
protected XQueryContext.HttpContext httpContext = null;
@@ -268,6 +269,8 @@ public void setProperties(Properties properties)
268269
key = (String)e.nextElement();
269270
if(key.equals(Namespaces.SAX_LEXICAL_HANDLER))
270271
{lexicalHandler = (LexicalHandler)properties.get(key);}
272+
else if (key.equals(EXistOutputKeys.USE_CHARACTER_MAPS))
273+
{useCharacterMaps = (Map<Integer, String>) properties.get(key);}
271274
else
272275
{setProperty(key, properties.getProperty(key));}
273276
}

exist-core/src/main/java/org/exist/util/serializer/AbstractSerializer.java

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323

2424
import org.exist.storage.serializers.EXistOutputKeys;
2525
import org.exist.util.serializer.json.JSONWriter;
26+
import org.exist.xquery.util.SerializerUtils;
2627

2728
import javax.xml.transform.OutputKeys;
2829
import java.io.Writer;
30+
import java.util.Map;
2931
import java.util.Properties;
3032

3133
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -35,40 +37,43 @@
3537
*/
3638
public abstract class AbstractSerializer {
3739

38-
protected final static int XML_WRITER = 0;
39-
protected final static int XHTML_WRITER = 1;
40-
protected final static int TEXT_WRITER = 2;
41-
protected final static int JSON_WRITER = 3;
42-
protected final static int XHTML5_WRITER = 4;
43-
protected final static int MICRO_XML_WRITER = 5;
44-
protected final static int HTML5_WRITER = 6;
40+
protected static final int XML_WRITER = 0;
41+
protected static final int XHTML_WRITER = 1;
42+
protected static final int TEXT_WRITER = 2;
43+
protected static final int JSON_WRITER = 3;
44+
protected static final int XHTML5_WRITER = 4;
45+
protected static final int MICRO_XML_WRITER = 5;
46+
protected static final int HTML5_WRITER = 6;
4547

46-
protected XMLWriter[] writers = {
48+
protected static final int CHARACTER_MAPPING_WRITER = 7;
49+
50+
protected SerializerWriter[] writers = {
4751
new IndentingXMLWriter(),
4852
new XHTMLWriter(),
4953
new TEXTWriter(),
5054
new JSONWriter(),
5155
new XHTML5Writer(),
5256
new MicroXmlWriter(),
53-
new HTML5Writer()
57+
new HTML5Writer(),
58+
new CharacterMappingWriter()
5459
};
5560

56-
protected final static Properties defaultProperties = new Properties();
61+
protected static final Properties defaultProperties = new Properties();
5762

5863
static {
5964
defaultProperties.setProperty(OutputKeys.ENCODING, UTF_8.name());
6065
defaultProperties.setProperty(OutputKeys.INDENT, "false");
6166
}
6267

6368
protected Properties outputProperties;
64-
protected XMLWriter receiver;
69+
protected SerializerWriter receiver;
6570

6671
public AbstractSerializer() {
6772
super();
6873
receiver = getDefaultWriter();
6974
}
7075

71-
protected XMLWriter getDefaultWriter() {
76+
protected SerializerWriter getDefaultWriter() {
7277
return writers[XML_WRITER];
7378
}
7479

@@ -88,38 +93,59 @@ public void setOutput(Writer writer, Properties properties) {
8893
htmlVersion = 1.0;
8994
}
9095

96+
final SerializerWriter baseSerializerWriter = getBaseSerializerWriter(method, htmlVersion);
97+
98+
final SerializerWriter serializerWriter;
99+
final CharacterMappingWriter characterMappingWriter = getCharacterMappingWriter();
100+
characterMappingWriter.setWrappedSerializerWriter(baseSerializerWriter);
101+
final Map<Integer, String> characterMap = SerializerUtils.getCharacterMap(outputProperties);
102+
if (characterMap == null || characterMap.size() == 0) {
103+
serializerWriter = baseSerializerWriter;
104+
} else {
105+
serializerWriter = characterMappingWriter;
106+
}
107+
108+
serializerWriter.setWriter(writer);
109+
serializerWriter.setOutputProperties(outputProperties);
110+
111+
receiver = serializerWriter;
112+
}
113+
114+
private CharacterMappingWriter getCharacterMappingWriter() {
115+
return (CharacterMappingWriter) writers[CHARACTER_MAPPING_WRITER];
116+
}
117+
118+
private SerializerWriter getBaseSerializerWriter(final String method, final double htmlVersion) {
119+
91120
if ("xhtml".equalsIgnoreCase(method)) {
92121
if (htmlVersion < 5.0) {
93-
receiver = writers[XHTML_WRITER];
122+
return writers[XHTML_WRITER];
94123
} else {
95-
receiver = writers[XHTML5_WRITER];
124+
return writers[XHTML5_WRITER];
96125
}
97126
} else if ("html".equals(method)) {
98127
if (htmlVersion < 5.0) {
99-
receiver = writers[XHTML_WRITER];
128+
return writers[XHTML_WRITER];
100129
} else {
101-
receiver = writers[HTML5_WRITER];
130+
return writers[HTML5_WRITER];
102131
}
103132
} else if("text".equalsIgnoreCase(method)) {
104-
receiver = writers[TEXT_WRITER];
133+
return writers[TEXT_WRITER];
105134
} else if ("json".equalsIgnoreCase(method)) {
106-
receiver = writers[JSON_WRITER];
135+
return writers[JSON_WRITER];
107136
} else if ("xhtml5".equalsIgnoreCase(method)) {
108-
receiver = writers[XHTML5_WRITER];
137+
return writers[XHTML5_WRITER];
109138
} else if ("html5".equalsIgnoreCase(method)) {
110-
receiver = writers[HTML5_WRITER];
139+
return writers[HTML5_WRITER];
111140
} else if("microxml".equalsIgnoreCase(method)) {
112-
receiver = writers[MICRO_XML_WRITER];
141+
return writers[MICRO_XML_WRITER];
113142
} else {
114-
receiver = writers[XML_WRITER];
143+
return writers[XML_WRITER];
115144
}
116-
117-
receiver.setWriter(writer);
118-
receiver.setOutputProperties(outputProperties);
119145
}
120146

121147
public void reset() {
122-
for (XMLWriter writer : writers) {
148+
for (SerializerWriter writer : writers) {
123149
writer.reset();
124150
}
125151
}

exist-core/src/main/java/org/exist/util/serializer/AdaptiveSerializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void setOutput(final Writer writer, final Properties properties) {
5757
} else {
5858
outputProperties = properties;
5959
}
60-
for (XMLWriter w: writers) {
60+
for (SerializerWriter w: writers) {
6161
w.setWriter(writer);
6262
w.setOutputProperties(outputProperties);
6363
}

exist-core/src/main/java/org/exist/util/serializer/AdaptiveWriter.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@
5656
*/
5757
public class AdaptiveWriter extends IndentingXMLWriter {
5858

59-
private final XMLWriter textWriter;
59+
private final SerializerWriter textWriter;
6060
private final DBBroker broker;
6161

6262
public AdaptiveWriter(final DBBroker broker, final Properties outputProperties,
63-
final XMLWriter textWriter) {
63+
final SerializerWriter textWriter) {
6464
this.broker = broker;
6565
this.textWriter = textWriter;
6666
setWriter(textWriter.getWriter());
@@ -189,7 +189,7 @@ private void writeAtomic(AtomicValue value) throws IOException, SAXException, XP
189189
writeText(sb);
190190
}
191191

192-
private void writeDouble(final DoubleValue item) throws XPathException, SAXException {
192+
private void writeDouble(final DoubleValue item) throws SAXException {
193193
final DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US);
194194
symbols.setExponentSeparator("e");
195195
final DecimalFormat df = new DecimalFormat("0.0##########################E0", symbols);
@@ -240,9 +240,8 @@ private void writeMap(final AbstractMapType map) throws SAXException, XPathExcep
240240
}
241241
}
242242

243-
private void writeFunctionItem(final FunctionReference item) throws XPathException, SAXException {
244-
final FunctionReference ref = item;
245-
final FunctionSignature signature = ref.getSignature();
243+
private void writeFunctionItem(final FunctionReference item) throws SAXException {
244+
final FunctionSignature signature = item.getSignature();
246245
final QName fn = signature.getName();
247246
final String name;
248247
if (fn == InlineFunction.INLINE_FUNCTION_QNAME) {

0 commit comments

Comments
 (0)