protected final Map<String, CachedValue<XmlNSDescriptor>> initNSDescriptorsMap() { Map<String, CachedValue<XmlNSDescriptor>> map = myNSDescriptorsMap; if (map == null) { RecursionGuard.StackStamp stamp = ourGuard.markStack(); map = computeNsDescriptorMap(); if (stamp.mayCacheNow()) { myNSDescriptorsMap = map; } } return map; }
@Nullable private BidirectionalMap<String, String> initNamespaceMaps(PsiElement parent) { BidirectionalMap<String, String> map = myNamespaceMap; if (map == null) { RecursionGuard.StackStamp stamp = ourGuard.markStack(); map = computeNamespaceMap(parent); if (stamp.mayCacheNow()) { myNamespaceMap = map; } } return map; }
@NotNull public String getNamespaceByPrefix(String prefix) { final PsiElement parent = getParent(); LOG.assertTrue(parent.isValid()); BidirectionalMap<String, String> map = initNamespaceMaps(parent); if (map != null) { final String ns = map.get(prefix); if (ns != null) return ns; } if (parent instanceof XmlTag) return ((XmlTag) parent).getNamespaceByPrefix(prefix); // The prefix 'xml' is by definition bound to the namespace name // http://www.w3.org/XML/1998/namespace. It MAY, but need not, be declared if (XML_NS_PREFIX.equals(prefix)) return XmlUtil.XML_NAMESPACE_URI; if (prefix.length() > 0 && !hasNamespaceDeclarations() && getNamespacePrefix().equals(prefix)) { // When there is no namespace declarations then qualified names should be just used in dtds // this implies that we may have "" namespace prefix ! (see last paragraph in Namespaces in // Xml, Section 5) String result = ourGuard.doPreventingRecursion( "getNsByPrefix", true, new Computable<String>() { @Override public String compute() { final String nsFromEmptyPrefix = getNamespaceByPrefix(""); final XmlNSDescriptor nsDescriptor = getNSDescriptor(nsFromEmptyPrefix, false); final XmlElementDescriptor descriptor = nsDescriptor != null ? nsDescriptor.getElementDescriptor(XmlTagImpl.this) : null; final String nameFromRealDescriptor = descriptor != null && descriptor.getDeclaration() != null && descriptor.getDeclaration().isPhysical() ? descriptor.getName() : ""; if (nameFromRealDescriptor.equals(getName())) return nsFromEmptyPrefix; return XmlUtil.EMPTY_URI; } }); if (result != null) { return result; } } return XmlUtil.EMPTY_URI; }
@NotNull public String getNamespace() { String cachedNamespace = myCachedNamespace; final long curModCount = getManager().getModificationTracker().getModificationCount(); if (cachedNamespace != null && myModCount == curModCount) { return cachedNamespace; } RecursionGuard.StackStamp stamp = ourGuard.markStack(); cachedNamespace = getNamespaceByPrefix(getNamespacePrefix()); if (!stamp.mayCacheNow()) { return cachedNamespace; } myCachedNamespace = cachedNamespace; myModCount = curModCount; return cachedNamespace; }
public XmlElementDescriptor getDescriptor() { final long curModCount = getManager().getModificationTracker().getModificationCount(); long curExtResourcesModCount = ExternalResourceManagerEx.getInstanceEx().getModificationCount(getProject()); if (myDescriptorModCount != curModCount || myExtResourcesModCount != curExtResourcesModCount) { if (myExtResourcesModCount != curExtResourcesModCount) { myNSDescriptorsMap = null; } RecursionGuard.StackStamp stamp = ourGuard.markStack(); XmlElementDescriptor descriptor = computeElementDescriptor(); if (!stamp.mayCacheNow()) { return descriptor; } myCachedDescriptor = descriptor; myDescriptorModCount = curModCount; myExtResourcesModCount = curExtResourcesModCount; } return myCachedDescriptor; }