📄 extensionpoint.java
字号:
Class extendedClass) throws IOException { this.extProfile = extProfile; this.extendedClass = extendedClass; initializeArbitraryXml(extProfile, extendedClass, this); } private final ExtensionProfile extProfile; private final Class extendedClass; public ElementHandler getChildHandler(String namespace, String localName, Attributes attrs) throws ParseException, IOException { // Try ExtensionPoint. It returns {@code null} if there's no handler. ElementHandler extensionHandler = getExtensionHandler(extProfile, extendedClass, namespace, localName, attrs); if (extensionHandler != null) { return extensionHandler; } return super.getChildHandler(namespace, localName, attrs); } } /** Retrieves the manifest for the specified class. */ protected Manifest getManifest( ExtensionProfile extProfile, Class<? extends ExtensionPoint> extendedClass) { if (manifest == null) { manifest = extProfile.getManifest(extendedClass); } return manifest; } /** * Generates XML corresponding to the type implementing {@link * ExtensionPoint}. The reason this routine is necessary is that the * embedded XML blob may contain namespace declarations. */ protected void generateStartElement(XmlWriter w, XmlWriter.Namespace namespace, String elementName, Collection<XmlWriter.Attribute> additionalAttrs, Collection<XmlWriter.Namespace> additionalNs) throws IOException { XmlBlob.startElement(w, namespace, elementName, xmlBlob, additionalAttrs, additionalNs); } /** * Generates XML corresponding to extended properties. Implementations in * extended classes should always call the base class to allow for nested * extensions. * * @param w * Output writer. * * @param extProfile * Extension profile for use by nested extensions. * * @throws IOException */ protected void generateExtensions(XmlWriter w, ExtensionProfile extProfile) throws IOException { for (Extension ext: nonRepeatingExtensionMap.values()) { ext.generate(w, extProfile); } for (List<Extension> extList: repeatingExtensionMap.values()) { w.startRepeatingElement(); for (Extension ext: extList) { ext.generate(w, extProfile); } w.endRepeatingElement(); } if (xmlBlob != null) { w.innerXml(xmlBlob.getBlob()); } } /** * Initializes parser handler's XML blob state. * Should be called by the handler's constructor in order to honor * {@link ExtensionProfile#declareArbitraryXmlExtension(Class)}. */ protected void initializeArbitraryXml(ExtensionProfile profile, Class extPoint, ElementHandler handler) throws IOException { Manifest manifest = getManifest(profile, extPoint); if (manifest != null && manifest.arbitraryXml) { handler.initializeXmlBlob(xmlBlob, /* mixedContent */ false, /* fullTextIndex */ false); } } /** * XML parser callback for extended properties. Implementations in * extended classes should always call the base class to allow for * nested extensions. * * @param extProfile * Extension profile for use by nested element handlers. * * @param extPoint * Current active ExtensionPoint class within which you're * looking for a handler for a nested extension element. * * @param namespaceUri * Namespace URI of the XML element. * * @param localName * Name of the XML element. * * @param attrs * Child element attributes. These attributes will be * communicated to the returned {@link ElementHandler} * through its {@link * ElementHandler#processAttribute(String, String, * String)} method. They are passed here because sometimes * the value of some attribute determines the element's * content type, so different element handlers may be * needed. * * @return Element handler for the custom tag or {@code null} if the tag * is not recognized. Unrecognized tags are stored in the XML blob. * * @throws ParseException * XML schema error. Could be a result of having a * duplicate entry, illegal contents (such as unrecognized * attributes or nested elements), etc. */ protected ElementHandler getExtensionHandler(ExtensionProfile extProfile, Class extPoint, String namespaceUri, String localName, Attributes attrs) throws ParseException, IOException { Manifest manifest = getManifest(extProfile, extPoint); if (manifest == null) { return null; } // Look for an explicit match, followed by a wildcarded namespace match. ExtensionDescription extDescription = manifest.supportedExtensions.get(new Pair(namespaceUri, localName)); if (extDescription == null) { extDescription = manifest.supportedExtensions.get(new Pair(namespaceUri, "*")); if (extDescription == null) { // extension point) could just live here. return null; } } Class<? extends Extension> extClass = extDescription.getExtensionClass(); if (extClass == null) { return null; } Extension extension = null; // If an aggregate extension type, retrieve existing instance (if any) if (extDescription.isAggregate()) { extension = getExtension(extClass); } boolean needsAdd = true; if (extension == null) { // Create an extension instance. try { extension = extClass.newInstance(); } catch (InstantiationException e) { throw new ParseException("Unable to create extension", e); } catch (IllegalAccessException e) { throw new ParseException("Unable to create extension", e); } } else { needsAdd = false; } // Retrieve the handler. ElementHandler handler = extension.getHandler(extProfile, namespaceUri, localName, attrs); // Store the new extension instance. if (needsAdd) { if (extDescription.isRepeatable()) { addRepeatingExtension(extension, extClass); } else { boolean added = addExtension(extension, extClass); if (!added) { throw new ParseException( "Duplicate extension element " + namespaceUri + ":" + localName); } } } return handler; } /** Checks whether all required extensions are present. */ protected void checkRequiredExtensions(Manifest manifest) throws ParseException { for (ExtensionDescription extDescription: manifest.supportedExtensions.values()) { Class extClass = extDescription.getExtensionClass(); if (extDescription.isRequired()) { boolean found = (extDescription.isRepeatable() ? repeatingExtensionMap.containsKey(extClass) : nonRepeatingExtensionMap.containsKey(extClass)); if (!found) { throw new ParseException( "Required extension element " + extDescription.getNamespace().getAlias() + ":" + extDescription.getNamespace().getUri() + " not found."); } } } } /** * ElementHandler implementation for handlers associated with an * ExtensionPoint class. Provides common initialization and * code for looking up handlers defined within the ExtensionProfile * associated with the ExtensionPoint. */ public class ExtensionHandler extends XmlParser.ElementHandler { protected ExtensionProfile extProfile; protected Class extendedClass; protected boolean hasExtensions; /** * Constructs a new Handler instance that process extensions on * a class associated with the ExtensionPoint * * @param profile * The extension profile associatd with the Handler. * * @param extendedClass * The extended class within the profile for this handler */ public ExtensionHandler(ExtensionProfile profile, Class extendedClass) throws java.io.IOException { this.extProfile = profile; this.extendedClass = extendedClass; // If the extended class is defined within the profile, then enable // extension handling and arbitrary XML handling. Manifest manifest = profile.getManifest(extendedClass); if (manifest != null) { hasExtensions = true; if (manifest.arbitraryXml) { initializeArbitraryXml(extProfile, extendedClass, this); } } } public XmlParser.ElementHandler getChildHandler(String namespace, String localName, Attributes attrs) throws ParseException, IOException { // If extensions have been defined for the extended class, then // look for a handler. if (hasExtensions) { XmlParser.ElementHandler extensionHandler = getExtensionHandler(extProfile, extendedClass, namespace, localName, attrs); if (extensionHandler != null) { return extensionHandler; } } return super.getChildHandler(namespace, localName, attrs); } public void processEndElement() throws ParseException { super.processEndElement(); // // Iterate through all contained Extension instances and enable them // to validate against the full ExtensionPoint state (including // sibling Extension instances). // for (Extension extension : nonRepeatingExtensionMap.values()) { if (extension instanceof ValidatingExtension) { ((ValidatingExtension) extension).validate(ExtensionPoint.this); } } for (List<Extension> extList : repeatingExtensionMap.values()) { for (Extension extension : extList) { if (extension instanceof ValidatingExtension) { ((ValidatingExtension) extension).validate(ExtensionPoint.this); } } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -