imToken v2.14.1版本的 MD5 值为:83050b2c91219b46832c8336279e7878
以下内容为反编译后的 XMPSerializerRDF.java 源代码,内容仅作参考
package com.adobe.internal.xmp.impl;
import com.adobe.internal.xmp.XMPConst;
import com.adobe.internal.xmp.XMPException;
import com.adobe.internal.xmp.XMPMeta;
import com.adobe.internal.xmp.XMPMetaFactory;
import com.adobe.internal.xmp.XMPSchemaRegistry;
import com.adobe.internal.xmp.options.SerializeOptions;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class XMPSerializerRDF {
private static final int DEFAULT_PAD = 2048;
private static final String PACKET_HEADER = "<?xpacket begin=\"\ufeff\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>";
private static final String PACKET_TRAILER = "<?xpacket end=\"";
private static final String PACKET_TRAILER2 = "\"?>";
static final Set RDF_ATTR_QUALIFIER = new HashSet(Arrays.asList(XMPConst.XML_LANG, "rdf:resource", "rdf:ID", "rdf:bagID", "rdf:nodeID"));
private static final String RDF_EMPTY_STRUCT = "<rdf:Description/>";
private static final String RDF_RDF_END = "</rdf:RDF>";
private static final String RDF_RDF_START = "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">";
private static final String RDF_SCHEMA_END = "</rdf:Description>";
private static final String RDF_SCHEMA_START = "<rdf:Description rdf:about=";
private static final String RDF_STRUCT_END = "</rdf:Description>";
private static final String RDF_STRUCT_START = "<rdf:Description";
private static final String RDF_XMPMETA_END = "</x:xmpmeta>";
private static final String RDF_XMPMETA_START = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"";
private SerializeOptions options;
private CountOutputStream outputStream;
private int padding;
private int unicodeSize = 1;
private OutputStreamWriter writer;
private XMPMetaImpl xmp;
public void serialize(XMPMeta xMPMeta, OutputStream outputStream, SerializeOptions serializeOptions) throws XMPException {
try {
this.outputStream = new CountOutputStream(outputStream);
this.writer = new OutputStreamWriter(this.outputStream, serializeOptions.getEncoding());
this.xmp = (XMPMetaImpl) xMPMeta;
this.options = serializeOptions;
this.padding = serializeOptions.getPadding();
this.writer = new OutputStreamWriter(this.outputStream, serializeOptions.getEncoding());
checkOptionsConsistence();
String serializeAsRDF = serializeAsRDF();
this.writer.flush();
addPadding(serializeAsRDF.length());
write(serializeAsRDF);
this.writer.flush();
this.outputStream.close();
} catch (IOException unused) {
throw new XMPException("Error writing to the OutputStream", 0);
}
}
private void addPadding(int i2) throws XMPException, IOException {
if (this.options.getExactPacketLength()) {
int bytesWritten = this.outputStream.getBytesWritten() + (i2 * this.unicodeSize);
int i3 = this.padding;
if (bytesWritten > i3) {
throw new XMPException("Can't fit into specified packet size", 107);
}
this.padding = i3 - bytesWritten;
}
this.padding /= this.unicodeSize;
int length = this.options.getNewline().length();
int i4 = this.padding;
if (i4 >= length) {
this.padding = i4 - length;
while (true) {
int i5 = this.padding;
int i6 = length + 100;
if (i5 >= i6) {
writeChars(100, ' ');
writeNewline();
this.padding -= i6;
} else {
writeChars(i5, ' ');
writeNewline();
return;
}
}
} else {
writeChars(i4, ' ');
}
}
protected void checkOptionsConsistence() throws XMPException {
if (this.options.getEncodeUTF16BE() | this.options.getEncodeUTF16LE()) {
this.unicodeSize = 2;
}
if (this.options.getExactPacketLength()) {
if (this.options.getOmitPacketWrapper() | this.options.getIncludeThumbnailPad()) {
throw new XMPException("Inconsistent options for exact size serialize", 103);
}
if ((this.options.getPadding() & (this.unicodeSize - 1)) != 0) {
throw new XMPException("Exact size must be a multiple of the Unicode element", 103);
}
} else if (this.options.getReadOnlyPacket()) {
if (this.options.getOmitPacketWrapper() | this.options.getIncludeThumbnailPad()) {
throw new XMPException("Inconsistent options for read-only packet", 103);
}
this.padding = 0;
} else if (this.options.getOmitPacketWrapper()) {
if (this.options.getIncludeThumbnailPad()) {
throw new XMPException("Inconsistent options for non-packet serialize", 103);
}
this.padding = 0;
} else {
if (this.padding == 0) {
this.padding = this.unicodeSize * 2048;
}
if (!this.options.getIncludeThumbnailPad() || this.xmp.doesPropertyExist("http://ns.adobe.com/xap/1.0/", "Thumbnails")) {
return;
}
this.padding += this.unicodeSize * 10000;
}
}
private String serializeAsRDF() throws IOException, XMPException {
int i2 = 0;
if (!this.options.getOmitPacketWrapper()) {
writeIndent(0);
write(PACKET_HEADER);
writeNewline();
}
if (!this.options.getOmitXmpMetaElement()) {
writeIndent(0);
write(RDF_XMPMETA_START);
if (!this.options.getOmitVersionAttribute()) {
write(XMPMetaFactory.getVersionInfo().getMessage());
}
write("\">");
writeNewline();
i2 = 1;
}
writeIndent(i2);
write(RDF_RDF_START);
writeNewline();
if (this.options.getUseCanonicalFormat()) {
serializeCanonicalRDFSchemas(i2);
} else {
serializeCompactRDFSchemas(i2);
}
writeIndent(i2);
write(RDF_RDF_END);
writeNewline();
if (!this.options.getOmitXmpMetaElement()) {
writeIndent(i2 - 1);
write(RDF_XMPMETA_END);
writeNewline();
}
String str = "";
if (this.options.getOmitPacketWrapper()) {
return "";
}
for (int baseIndent = this.options.getBaseIndent(); baseIndent > 0; baseIndent--) {
str = str + this.options.getIndent();
}
StringBuilder sb = new StringBuilder();
sb.append(str + PACKET_TRAILER);
sb.append(this.options.getReadOnlyPacket() ? 'r' : 'w');
return sb.toString() + PACKET_TRAILER2;
}
private void serializeCanonicalRDFSchemas(int i2) throws IOException, XMPException {
if (this.xmp.getRoot().getChildrenLength() > 0) {
startOuterRDFDescription(this.xmp.getRoot(), i2);
Iterator iterateChildren = this.xmp.getRoot().iterateChildren();
while (iterateChildren.hasNext()) {
serializeCanonicalRDFSchema((XMPNode) iterateChildren.next(), i2);
}
endOuterRDFDescription(i2);
return;
}
writeIndent(i2 + 1);
write(RDF_SCHEMA_START);
writeTreeName();
write("/>");
writeNewline();
}
private void writeTreeName() throws IOException {
write(34);
String name = this.xmp.getRoot().getName();
if (name != null) {
appendNodeValue(name, true);
}
write(34);
}
private void serializeCompactRDFSchemas(int i2) throws IOException, XMPException {
int i3 = i2 + 1;
writeIndent(i3);
write(RDF_SCHEMA_START);
writeTreeName();
HashSet hashSet = new HashSet();
hashSet.add("xml");
hashSet.add("rdf");
Iterator iterateChildren = this.xmp.getRoot().iterateChildren();
while (iterateChildren.hasNext()) {
declareUsedNamespaces((XMPNode) iterateChildren.next(), hashSet, i2 + 3);
}
Iterator iterateChildren2 = this.xmp.getRoot().iterateChildren();
boolean z2 = true;
while (iterateChildren2.hasNext()) {
z2 &= serializeCompactRDFAttrProps((XMPNode) iterateChildren2.next(), i2 + 2);
}
if (!z2) {
write(62);
writeNewline();
Iterator iterateChildren3 = this.xmp.getRoot().iterateChildren();
while (iterateChildren3.hasNext()) {
serializeCompactRDFElementProps((XMPNode) iterateChildren3.next(), i2 + 2);
}
writeIndent(i3);
write("</rdf:Description>");
writeNewline();
return;
}
write("/>");
writeNewline();
}
private boolean serializeCompactRDFAttrProps(XMPNode xMPNode, int i2) throws IOException {
Iterator iterateChildren = xMPNode.iterateChildren();
boolean z2 = true;
while (iterateChildren.hasNext()) {
XMPNode xMPNode2 = (XMPNode) iterateChildren.next();
if (canBeRDFAttrProp(xMPNode2)) {
writeNewline();
writeIndent(i2);
write(xMPNode2.getName());
write("=\"");
appendNodeValue(xMPNode2.getValue(), true);
write(34);
} else {
z2 = false;
}
}
return z2;
}
private void serializeCompactRDFElementProps(XMPNode xMPNode, int i2) throws IOException, XMPException {
boolean z2;
boolean z3;
Iterator iterateChildren = xMPNode.iterateChildren();
while (iterateChildren.hasNext()) {
XMPNode xMPNode2 = (XMPNode) iterateChildren.next();
if (!canBeRDFAttrProp(xMPNode2)) {
String name = xMPNode2.getName();
if ("[]".equals(name)) {
name = "rdf:li";
}
writeIndent(i2);
write(60);
write(name);
Iterator iterateQualifier = xMPNode2.iterateQualifier();
boolean z4 = false;
boolean z5 = false;
while (true) {
z2 = true;
if (!iterateQualifier.hasNext()) {
break;
}
XMPNode xMPNode3 = (XMPNode) iterateQualifier.next();
if (RDF_ATTR_QUALIFIER.contains(xMPNode3.getName())) {
z5 = "rdf:resource".equals(xMPNode3.getName());
write(32);
write(xMPNode3.getName());
write("=\"");
appendNodeValue(xMPNode3.getValue(), true);
write(34);
} else {
z4 = true;
}
}
if (z4) {
serializeCompactRDFGeneralQualifier(i2, xMPNode2);
} else {
if (!xMPNode2.getOptions().isCompositeProperty()) {
Object[] serializeCompactRDFSimpleProp = serializeCompactRDFSimpleProp(xMPNode2);
boolean booleanValue = ((Boolean) serializeCompactRDFSimpleProp[0]).booleanValue();
z3 = ((Boolean) serializeCompactRDFSimpleProp[1]).booleanValue();
z2 = booleanValue;
} else if (xMPNode2.getOptions().isArray()) {
serializeCompactRDFArrayProp(xMPNode2, i2);
} else {
z2 = serializeCompactRDFStructProp(xMPNode2, i2, z5);
z3 = true;
}
if (z2) {
if (z3) {
writeIndent(i2);
}
write("</");
write(name);
write(62);
writeNewline();
}
}
z3 = true;
if (z2) {
}
}
}
}
private Object[] serializeCompactRDFSimpleProp(XMPNode xMPNode) throws IOException {
Boolean bool = Boolean.TRUE;
Boolean bool2 = Boolean.TRUE;
if (xMPNode.getOptions().isURI()) {
write(" rdf:resource=\"");
appendNodeValue(xMPNode.getValue(), true);
write("\"/>");
writeNewline();
bool = Boolean.FALSE;
} else if (xMPNode.getValue() == null || xMPNode.getValue().length() == 0) {
write("/>");
writeNewline();
bool = Boolean.FALSE;
} else {
write(62);
appendNodeValue(xMPNode.getValue(), false);
bool2 = Boolean.FALSE;
}
return new Object[]{bool, bool2};
}
private void serializeCompactRDFArrayProp(XMPNode xMPNode, int i2) throws IOException, XMPException {
write(62);
writeNewline();
int i3 = i2 + 1;
emitRDFArrayTag(xMPNode, true, i3);
if (xMPNode.getOptions().isArrayAltText()) {
XMPNodeUtils.normalizeLangArray(xMPNode);
}
serializeCompactRDFElementProps(xMPNode, i2 + 2);
emitRDFArrayTag(xMPNode, false, i3);
}
private boolean serializeCompactRDFStructProp(XMPNode xMPNode, int i2, boolean z2) throws XMPException, IOException {
Iterator iterateChildren = xMPNode.iterateChildren();
boolean z3 = false;
boolean z4 = false;
while (iterateChildren.hasNext()) {
if (canBeRDFAttrProp((XMPNode) iterateChildren.next())) {
z3 = true;
} else {
z4 = true;
}
if (z3 && z4) {
break;
}
}
if (z2 && z4) {
throw new XMPException("Can't mix rdf:resource qualifier and element fields", 202);
}
if (!xMPNode.hasChildren()) {
write(" rdf:parseType=\"Resource\"/>");
writeNewline();
return false;
} else if (!z4) {
serializeCompactRDFAttrProps(xMPNode, i2 + 1);
write("/>");
writeNewline();
return false;
} else {
if (!z3) {
write(" rdf:parseType=\"Resource\">");
writeNewline();
serializeCompactRDFElementProps(xMPNode, i2 + 1);
} else {
write(62);
writeNewline();
int i3 = i2 + 1;
writeIndent(i3);
write(RDF_STRUCT_START);
serializeCompactRDFAttrProps(xMPNode, i2 + 2);
write(">");
writeNewline();
serializeCompactRDFElementProps(xMPNode, i3);
writeIndent(i3);
write("</rdf:Description>");
writeNewline();
}
return true;
}
}
private void serializeCompactRDFGeneralQualifier(int i2, XMPNode xMPNode) throws IOException, XMPException {
write(" rdf:parseType=\"Resource\">");
writeNewline();
int i3 = i2 + 1;
serializeCanonicalRDFProperty(xMPNode, false, true, i3);
Iterator iterateQualifier = xMPNode.iterateQualifier();
while (iterateQualifier.hasNext()) {
serializeCanonicalRDFProperty((XMPNode) iterateQualifier.next(), false, false, i3);
}
}
private void serializeCanonicalRDFSchema(XMPNode xMPNode, int i2) throws IOException, XMPException {
Iterator iterateChildren = xMPNode.iterateChildren();
while (iterateChildren.hasNext()) {
serializeCanonicalRDFProperty((XMPNode) iterateChildren.next(), this.options.getUseCanonicalFormat(), false, i2 + 2);
}
}
private void declareUsedNamespaces(XMPNode xMPNode, Set set, int i2) throws IOException {
if (xMPNode.getOptions().isSchemaNode()) {
declareNamespace(xMPNode.getValue().substring(0, xMPNode.getValue().length() - 1), xMPNode.getName(), set, i2);
} else if (xMPNode.getOptions().isStruct()) {
Iterator iterateChildren = xMPNode.iterateChildren();
while (iterateChildren.hasNext()) {
declareNamespace(((XMPNode) iterateChildren.next()).getName(), null, set, i2);
}
}
Iterator iterateChildren2 = xMPNode.iterateChildren();
while (iterateChildren2.hasNext()) {
declareUsedNamespaces((XMPNode) iterateChildren2.next(), set, i2);
}
Iterator iterateQualifier = xMPNode.iterateQualifier();
while (iterateQualifier.hasNext()) {
XMPNode xMPNode2 = (XMPNode) iterateQualifier.next();
declareNamespace(xMPNode2.getName(), null, set, i2);
declareUsedNamespaces(xMPNode2, set, i2);
}
}
private void declareNamespace(String str, String str2, Set set, int i2) throws IOException {
if (str2 == null) {
QName qName = new QName(str);
if (!qName.hasPrefix()) {
return;
}
str = qName.getPrefix();
XMPSchemaRegistry schemaRegistry = XMPMetaFactory.getSchemaRegistry();
str2 = schemaRegistry.getNamespaceURI(str + ":");
declareNamespace(str, str2, set, i2);
}
if (set.contains(str)) {
return;
}
writeNewline();
writeIndent(i2);
write("xmlns:");
write(str);
write("=\"");
write(str2);
write(34);
set.add(str);
}
private void startOuterRDFDescription(XMPNode xMPNode, int i2) throws IOException {
writeIndent(i2 + 1);
write(RDF_SCHEMA_START);
writeTreeName();
HashSet hashSet = new HashSet();
hashSet.add("xml");
hashSet.add("rdf");
declareUsedNamespaces(xMPNode, hashSet, i2 + 3);
write(62);
writeNewline();
}
private void endOuterRDFDescription(int i2) throws IOException {
writeIndent(i2 + 1);
write("</rdf:Description>");
writeNewline();
}
private void serializeCanonicalRDFProperty(XMPNode xMPNode, boolean z2, boolean z3, int i2) throws IOException, XMPException {
boolean z4;
int i3 = i2;
String name = xMPNode.getName();
if (z3) {
name = "rdf:value";
} else if ("[]".equals(name)) {
name = "rdf:li";
}
writeIndent(i3);
write(60);
write(name);
Iterator iterateQualifier = xMPNode.iterateQualifier();
boolean z5 = false;
boolean z6 = false;
boolean z7 = false;
while (true) {
z4 = true;
if (!iterateQualifier.hasNext()) {
break;
}
XMPNode xMPNode2 = (XMPNode) iterateQualifier.next();
if (RDF_ATTR_QUALIFIER.contains(xMPNode2.getName())) {
z7 = "rdf:resource".equals(xMPNode2.getName());
if (!z3) {
write(32);
write(xMPNode2.getName());
write("=\"");
appendNodeValue(xMPNode2.getValue(), true);
write(34);
}
} else {
z6 = true;
}
}
if (!z6 || z3) {
if (!xMPNode.getOptions().isCompositeProperty()) {
if (xMPNode.getOptions().isURI()) {
write(" rdf:resource=\"");
appendNodeValue(xMPNode.getValue(), true);
write("\"/>");
writeNewline();
} else if (xMPNode.getValue() == null || "".equals(xMPNode.getValue())) {
write("/>");
writeNewline();
} else {
write(62);
appendNodeValue(xMPNode.getValue(), false);
z4 = false;
z5 = true;
}
} else {
if (xMPNode.getOptions().isArray()) {
write(62);
writeNewline();
int i4 = i3 + 1;
emitRDFArrayTag(xMPNode, true, i4);
if (xMPNode.getOptions().isArrayAltText()) {
XMPNodeUtils.normalizeLangArray(xMPNode);
}
Iterator iterateChildren = xMPNode.iterateChildren();
while (iterateChildren.hasNext()) {
serializeCanonicalRDFProperty((XMPNode) iterateChildren.next(), z2, false, i3 + 2);
}
emitRDFArrayTag(xMPNode, false, i4);
} else if (!z7) {
if (!xMPNode.hasChildren()) {
if (z2) {
write(">");
writeNewline();
writeIndent(i3 + 1);
write(RDF_EMPTY_STRUCT);
z5 = true;
} else {
write(" rdf:parseType=\"Resource\"/>");
}
writeNewline();
} else {
if (z2) {
write(">");
writeNewline();
i3++;
writeIndent(i3);
write(RDF_STRUCT_START);
write(">");
} else {
write(" rdf:parseType=\"Resource\">");
}
writeNewline();
Iterator iterateChildren2 = xMPNode.iterateChildren();
while (iterateChildren2.hasNext()) {
serializeCanonicalRDFProperty((XMPNode) iterateChildren2.next(), z2, false, i3 + 1);
}
if (z2) {
writeIndent(i3);
write("</rdf:Description>");
writeNewline();
i3--;
}
}
} else {
Iterator iterateChildren3 = xMPNode.iterateChildren();
while (iterateChildren3.hasNext()) {
XMPNode xMPNode3 = (XMPNode) iterateChildren3.next();
if (!canBeRDFAttrProp(xMPNode3)) {
throw new XMPException("Can't mix rdf:resource and complex fields", 202);
}
writeNewline();
writeIndent(i3 + 1);
write(32);
write(xMPNode3.getName());
write("=\"");
appendNodeValue(xMPNode3.getValue(), true);
write(34);
}
write("/>");
writeNewline();
}
z5 = true;
}
} else if (z7) {
throw new XMPException("Can't mix rdf:resource and general qualifiers", 202);
} else {
if (z2) {
write(">");
writeNewline();
i3++;
writeIndent(i3);
write(RDF_STRUCT_START);
write(">");
} else {
write(" rdf:parseType=\"Resource\">");
}
writeNewline();
int i5 = i3 + 1;
serializeCanonicalRDFProperty(xMPNode, z2, true, i5);
Iterator iterateQualifier2 = xMPNode.iterateQualifier();
while (iterateQualifier2.hasNext()) {
XMPNode xMPNode4 = (XMPNode) iterateQualifier2.next();
if (!RDF_ATTR_QUALIFIER.contains(xMPNode4.getName())) {
serializeCanonicalRDFProperty(xMPNode4, z2, false, i5);
}
}
if (z2) {
writeIndent(i3);
write("</rdf:Description>");
writeNewline();
i3--;
}
z5 = true;
}
if (z5) {
if (z4) {
writeIndent(i3);
}
write("</");
write(name);
write(62);
writeNewline();
}
}
private void emitRDFArrayTag(XMPNode xMPNode, boolean z2, int i2) throws IOException {
if (z2 || xMPNode.hasChildren()) {
writeIndent(i2);
write(z2 ? "<rdf:" : "</rdf:");
if (xMPNode.getOptions().isArrayAlternate()) {
write("Alt");
} else if (xMPNode.getOptions().isArrayOrdered()) {
write("Seq");
} else {
write("Bag");
}
if (z2 && !xMPNode.hasChildren()) {
write("/>");
} else {
write(">");
}
writeNewline();
}
}
private void appendNodeValue(String str, boolean z2) throws IOException {
if (str == null) {
str = "";
}
write(Utils.escapeXML(str, z2, true));
}
private boolean canBeRDFAttrProp(XMPNode xMPNode) {
return (xMPNode.hasQualifier() || xMPNode.getOptions().isURI() || xMPNode.getOptions().isCompositeProperty() || "[]".equals(xMPNode.getName())) ? false : true;
}
private void writeIndent(int i2) throws IOException {
for (int baseIndent = this.options.getBaseIndent() + i2; baseIndent > 0; baseIndent--) {
this.writer.write(this.options.getIndent());
}
}
private void write(int i2) throws IOException {
this.writer.write(i2);
}
private void write(String str) throws IOException {
this.writer.write(str);
}
private void writeChars(int i2, char c2) throws IOException {
while (i2 > 0) {
this.writer.write(c2);
i2--;
}
}
private void writeNewline() throws IOException {
this.writer.write(this.options.getNewline());
}
}