📄 parserdf.java
字号:
BADRDF); } } // Create the right kind of child node and visit the attributes again // to add the fields or qualifiers. // ! Because of implementation vagaries, // the xmpParent is the tree root for top level properties. // ! The schema is found, created if necessary, by addChildNode. XMPNode childNode = addChildNode(xmp, xmpParent, xmlNode, "", isTopLevel); boolean childIsStruct = false; if (hasValueAttr || hasResourceAttr) { childNode.setValue(valueNode != null ? valueNode.getNodeValue() : ""); if (!hasValueAttr) { // ! Might have both rdf:value and rdf:resource. childNode.getOptions().setURI(true); } } else if (hasPropertyAttrs) { childNode.getOptions().setStruct(true); childIsStruct = true; } for (int i = 0; i < xmlNode.getAttributes().getLength(); i++) { Node attribute = xmlNode.getAttributes().item(i); if (attribute == valueNode || "xmlns".equals(attribute.getPrefix()) || (attribute.getPrefix() == null && "xmlns".equals(attribute.getNodeName()))) { continue; // Skip the rdf:value or rdf:resource attribute holding the value. } int attrTerm = getRDFTermKind (attribute); switch (attrTerm) { case RDFTERM_ID : case RDFTERM_NODE_ID : break; // Ignore all rdf:ID and rdf:nodeID attributes. case RDFTERM_RESOURCE : addQualifierNode(childNode, "rdf:resource", attribute.getNodeValue()); break; case RDFTERM_OTHER : if (!childIsStruct) { addQualifierNode( childNode, attribute.getNodeName(), attribute.getNodeValue()); } else if (XML_LANG.equals(attribute.getNodeName())) { addQualifierNode (childNode, XML_LANG, attribute.getNodeValue()); } else { addChildNode (xmp, childNode, attribute, attribute.getNodeValue(), false); } break; default : throw new XMPException("Unrecognized attribute of empty property element", BADRDF); } } } /** * Adds a child node. * * @param xmp the xmp metadata object that is generated * @param xmpParent the parent xmp node * @param xmlNode the currently processed XML node * @param value Node value * @param isTopLevel Flag if the node is a top-level node * @return Returns the newly created child node. * @throws XMPException thown on parsing errors */ private static XMPNode addChildNode(XMPMetaImpl xmp, XMPNode xmpParent, Node xmlNode, String value, boolean isTopLevel) throws XMPException { XMPSchemaRegistry registry = XMPMetaFactory.getSchemaRegistry(); String namespace = xmlNode.getNamespaceURI(); String childName; if (namespace != null) { if (NS_DC_DEPRECATED.equals(namespace)) { // Fix a legacy DC namespace namespace = NS_DC; } String prefix = registry.getNamespacePrefix(namespace); if (prefix == null) { prefix = xmlNode.getPrefix() != null ? xmlNode.getPrefix() : DEFAULT_PREFIX; prefix = registry.registerNamespace(namespace, prefix); } childName = prefix + xmlNode.getLocalName(); } else { throw new XMPException( "XML namespace required for all elements and attributes", BADRDF); } // create schema node if not already there PropertyOptions childOptions = new PropertyOptions(); boolean isAlias = false; if (isTopLevel) { // Lookup the schema node, adjust the XMP parent pointer. // Incoming parent must be the tree root. XMPNode schemaNode = XMPNodeUtils.findSchemaNode(xmp.getRoot(), namespace, DEFAULT_PREFIX, true); schemaNode.setImplicit(false); // Clear the implicit node bit. // need runtime check for proper 32 bit code. xmpParent = schemaNode; // If this is an alias set the alias flag in the node // and the hasAliases flag in the tree. if (registry.findAlias(childName) != null) { isAlias = true; xmp.getRoot().setHasAliases(true); schemaNode.setHasAliases(true); } } // Make sure that this is not a duplicate of a named node. boolean isArrayItem = "rdf:li".equals(childName); boolean isValueNode = "rdf:value".equals(childName); // Create XMP node and so some checks XMPNode newChild = new XMPNode( childName, value, childOptions); newChild.setAlias(isAlias); // Add the new child to the XMP parent node, a value node first. if (!isValueNode) { xmpParent.addChild(newChild); } else { xmpParent.addChild(1, newChild); } if (isValueNode) { if (isTopLevel || !xmpParent.getOptions().isStruct()) { throw new XMPException("Misplaced rdf:value element", BADRDF); } xmpParent.setHasValueChild(true); } if (isArrayItem) { if (!xmpParent.getOptions().isArray()) { throw new XMPException("Misplaced rdf:li element", BADRDF); } newChild.setName(ARRAY_ITEM_NAME); } return newChild; } /** * Adds a qualifier node. * * @param xmpParent the parent xmp node * @param name the name of the qualifier which has to be * QName including the <b>default prefix</b> * @param value the value of the qualifier * @return Returns the newly created child node. * @throws XMPException thown on parsing errors */ private static XMPNode addQualifierNode(XMPNode xmpParent, String name, String value) throws XMPException { boolean isLang = XML_LANG.equals(name); boolean isCompact = "pxmp:compact".equals(name); XMPNode newQual = null; if (isCompact) { if (xmpParent.getOptions().isCompositeProperty()) { throw new XMPException("Only structs and arrays can be compact", BADXMP); } xmpParent.getOptions().setCompact(true); } else { // normalize value of language qualifiers newQual = new XMPNode(name, isLang ? Utils.normalizeLangValue(value) : value, null); xmpParent.addQualifier(newQual); } return newQual; } /** * The parent is an RDF pseudo-struct containing an rdf:value field. Fix the * XMP data model. The rdf:value node must be the first child, the other * children are qualifiers. The form, value, and children of the rdf:value * node are the real ones. The rdf:value node's qualifiers must be added to * the others. * * @param xmpParent the parent xmp node * @throws XMPException thown on parsing errors */ private static void fixupQualifiedNode(XMPNode xmpParent) throws XMPException { assert xmpParent.getOptions().isStruct() && xmpParent.hasChildren(); XMPNode valueNode = xmpParent.getChild(1); assert "rdf:value".equals(valueNode.getName()); // Move the qualifiers on the value node to the parent. // Make sure an xml:lang qualifier stays at the front. // Check for duplicate names between the value node's qualifiers and the parent's children. // The parent's children are about to become qualifiers. Check here, between the groups. // Intra-group duplicates are caught by XMPNode#addChild(...). if (valueNode.getOptions().getHasLanguage()) { if (xmpParent.getOptions().getHasLanguage()) { throw new XMPException("Redundant xml:lang for rdf:value element", BADXMP); } XMPNode langQual = valueNode.getQualifier(1); valueNode.removeQualifier(langQual); xmpParent.addQualifier(langQual); } // Start the remaining copy after the xml:lang qualifier. for (int i = 1; i <= valueNode.getQualifierLength(); i++) { XMPNode qualifier = valueNode.getQualifier(i); xmpParent.addQualifier(qualifier); } // Change the parent's other children into qualifiers. // This loop starts at 1, child 0 is the rdf:value node. for (int i = 2; i <= xmpParent.getChildrenLength(); i++) { XMPNode qualifier = xmpParent.getChild(i); if ("pxmp:compact".equals(qualifier.getName())) { // Compactness is an option bit, not an actual qualifier. if (!xmpParent.getOptions().isCompositeProperty()) { throw new XMPException("Only structs and arrays can be compact", BADXMP); } xmpParent.getOptions().setCompact(true); } else { xmpParent.addQualifier(qualifier); } } // Move the options and value last, other checks need the parent's original options. // Move the value node's children to be the parent's children. assert xmpParent.getOptions().isStruct() || xmpParent.getHasValueChild(); xmpParent.setHasValueChild(false); xmpParent.getOptions().setStruct(false); xmpParent.getOptions().mergeWith(valueNode.getOptions()); xmpParent.setValue(valueNode.getValue()); xmpParent.removeChildren(); for (Iterator it = valueNode.iterateChildren(); it.hasNext();) { XMPNode child = (XMPNode) it.next(); xmpParent.addChild(child); } } /** * Checks if the node is a white space. * @param node an XML-node * @return Returns whether the node is a whitespace node, * i.e. a text node that contains only whitespaces. */ private static boolean isWhitespaceNode(Node node) { if (node.getNodeType() != Node.TEXT_NODE) { return false; } String value = node.getNodeValue(); for (int i = 0; i < value.length(); i++) { if (!Character.isWhitespace(value.charAt(i))) { return false; } } return true; } /** * 7.2.6 propertyElementURIs * anyURI - ( coreSyntaxTerms | rdf:Description | oldTerms ) * * @param term the term id * @return Return true if the term is a property element name. */ private static boolean isPropertyElementName(int term) { if (term == RDFTERM_DESCRIPTION || isOldTerm(term)) { return false; } else { return (!isCoreSyntaxTerm(term)); } } /** * 7.2.4 oldTerms<br> * rdf:aboutEach | rdf:aboutEachPrefix | rdf:bagID * * @param term the term id * @return Returns true if the term is an old term. */ private static boolean isOldTerm(int term) { return RDFTERM_FIRST_OLD <= term && term <= RDFTERM_LAST_OLD; } /** * 7.2.2 coreSyntaxTerms<br> * rdf:RDF | rdf:ID | rdf:about | rdf:parseType | rdf:resource | rdf:nodeID | * rdf:datatype * * @param term the term id * @return Return true if the term is a core syntax term */ private static boolean isCoreSyntaxTerm(int term) { return RDFTERM_FIRST_CORE <= term && term <= RDFTERM_LAST_CORE; } /** * Determines the ID for a certain RDF Term. * Arranged to hopefully minimize the parse time for large XMP. * * @param node an XML node * @return Returns the term ID. */ private static int getRDFTermKind(Node node) { String localName = node.getLocalName(); String namespace = node.getNamespaceURI(); if ( namespace == null && ("about".equals(localName) || "ID".equals(localName)) && (node instanceof Attr) && NS_RDF.equals(((Attr) node).getOwnerElement().getNamespaceURI()) ) { namespace = NS_RDF; } if (NS_RDF.equals(namespace)) { if ("li".equals(localName)) { return RDFTERM_LI; } else if ("parseType".equals(localName)) { return RDFTERM_PARSE_TYPE; } else if ("Description".equals(localName)) { return RDFTERM_DESCRIPTION; } else if ("about".equals(localName)) { return RDFTERM_ABOUT; } else if ("resource".equals(localName)) { return RDFTERM_RESOURCE; } else if ("RDF".equals(localName)) { return RDFTERM_RDF; } else if ("ID".equals(localName)) { return RDFTERM_ID; } else if ("nodeID".equals(localName)) { return RDFTERM_NODE_ID; } else if ("datatype".equals(localName)) { return RDFTERM_DATATYPE; } else if ("aboutEach".equals(localName)) { return RDFTERM_ABOUT_EACH; } else if ("aboutEachPrefix".equals(localName)) { return RDFTERM_ABOUT_EACH_PREFIX; } else if ("bagID".equals(localName)) { return RDFTERM_BAG_ID; } } return RDFTERM_OTHER; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -