@NotNull public Map<String, String> getLocalNamespaceDeclarations() { Map<String, String> namespaces = new THashMap<String, String>(); for (final XmlAttribute attribute : getAttributes()) { if (!attribute.isNamespaceDeclaration() || attribute.getValue() == null) continue; // xmlns -> "", xmlns:a -> a final String localName = attribute.getLocalName(); namespaces.put(localName.equals(attribute.getName()) ? "" : localName, attribute.getValue()); } return namespaces; }
@Override public void visitXmlAttributeValue(XmlAttributeValue value) { final PsiElement parent = value.getParent(); if (!(parent instanceof XmlAttribute)) { checkReferences(value); return; } XmlAttribute attribute = (XmlAttribute) parent; XmlTag tag = attribute.getParent(); XmlElementDescriptor elementDescriptor = tag.getDescriptor(); XmlAttributeDescriptor attributeDescriptor = elementDescriptor != null ? elementDescriptor.getAttributeDescriptor(attribute) : null; if (attributeDescriptor != null && !skipValidation(value)) { String error = attributeDescriptor.validateValue(value, attribute.getValue()); if (error != null) { addToResults(HighlightInfo.createHighlightInfo(getTagProblemInfoType(tag), value, error)); return; } } checkReferences(value); }
@NotNull public PsiReference[] getReferencesByElement( @NotNull PsiElement element, @NotNull final ProcessingContext context) { final AntTarget target = (AntTarget) element; final XmlAttribute attr = target.getSourceElement().getAttribute("depends", null); if (attr == null) { return PsiReference.EMPTY_ARRAY; } final XmlAttributeValue xmlAttributeValue = attr.getValueElement(); if (xmlAttributeValue == null) { return PsiReference.EMPTY_ARRAY; } int offsetInPosition = xmlAttributeValue.getTextRange().getStartOffset() - target.getTextRange().getStartOffset() + 1; final String value = attr.getValue(); final List<PsiReference> result = PsiReferenceListSpinAllocator.alloc(); try { final StringBuilder builder = StringBuilderSpinAllocator.alloc(); try { int i = 0; int rightBound; final int valueLen = value.length(); do { rightBound = (i < valueLen) ? value.indexOf(',', i) : valueLen; if (rightBound < 0) rightBound = valueLen; builder.setLength(0); int j = i; for (; j < rightBound; ++j) { builder.append(value.charAt(j)); } j = 0; final int len = builder.length(); for (; j < len; ++j) { if (!Character.isWhitespace(builder.charAt(j))) break; } final String targetName = (len == 0 || j == len) ? "" : builder.substring(j); result.add( new AntTargetReference( target, targetName, new TextRange( offsetInPosition + i + j, offsetInPosition + i + j + targetName.length()), attr)); i = rightBound + 1; } while (rightBound < valueLen); return (result.size() > 0) ? result.toArray(new PsiReference[result.size()]) : PsiReference.EMPTY_ARRAY; } finally { StringBuilderSpinAllocator.dispose(builder); } } finally { PsiReferenceListSpinAllocator.dispose(result); } }
private Collection<SchemaTypeInfo> gatherInheritors(XmlTagImpl xml) { XmlAttribute name = getNameAttr(xml); if (name == null || StringUtil.isEmptyOrSpaces(name.getValue())) return null; String localName = name.getValue(); final boolean hasPrefix = localName.contains(":"); localName = hasPrefix ? localName.substring(localName.indexOf(':') + 1) : localName; final String nsPrefix = hasPrefix ? name.getValue().substring(0, name.getValue().indexOf(':')) : null; final XmlFile file = XmlUtil.getContainingFile(xml); if (file == null) return null; final Project project = file.getProject(); if (project == null) return null; final Set<SchemaTypeInfo> result = new HashSet<SchemaTypeInfo>(); final ArrayDeque<SchemaTypeInfo> queue = new ArrayDeque<SchemaTypeInfo>(); String nsUri; if (!hasPrefix) { nsUri = getDefaultNs(file); } else { nsUri = XmlUtil.findNamespaceByPrefix(nsPrefix, file.getRootTag()); } if (nsUri == null) return null; queue.add(new SchemaTypeInfo(localName, true, nsUri)); final PairConvertor<String, String, List<Set<SchemaTypeInfo>>> worker = SchemaTypeInheritanceIndex.getWorker(project, file.getContainingFile().getVirtualFile()); while (!queue.isEmpty()) { final SchemaTypeInfo info = queue.removeFirst(); final List<Set<SchemaTypeInfo>> childrenOfType = worker.convert(info.getNamespaceUri(), info.getTagName()); for (Set<SchemaTypeInfo> infos : childrenOfType) { for (SchemaTypeInfo typeInfo : infos) { if (typeInfo.isIsTypeName()) { queue.add(typeInfo); } result.add(typeInfo); } } } return result; }
private boolean isCertainTypeElement( XmlTagImpl xml, final String typeName, final String nsPrefix) { if (!isTypeElement(xml)) return false; final XmlAttribute name = getNameAttr(xml); if (name == null) return false; final String value = name.getValue(); if (value == null) return false; final String localName = XmlUtil.findLocalNameByQualifiedName(value); return typeName.equals(localName) && nsPrefix.equals(XmlUtil.findPrefixByQualifiedName(value)); }
@NotNull public PsiReference[] getReferencesByElement( @NotNull PsiElement element, @NotNull final ProcessingContext context) { boolean soft = myDefaultSoft; if (element instanceof XmlAttributeValue) { final XmlAttribute xmlAttribute = (XmlAttribute) element.getParent(); if (element.getTextLength() < 2) { return PsiReference.EMPTY_ARRAY; } final XmlTag tag = xmlAttribute.getParent(); String value = null; String bundle = tag.getAttributeValue("bundle"); if ("key".equals(xmlAttribute.getName())) { value = xmlAttribute.getValue(); } else if ("groupKey".equals(xmlAttribute.getName())) { value = xmlAttribute.getValue(); final String groupBundle = tag.getAttributeValue("groupBundle"); if (groupBundle != null) { bundle = groupBundle; } } if (value != null) { return new PsiReference[] { new PropertyReference(value, xmlAttribute.getValueElement(), bundle, soft) { @Override protected List<PropertiesFile> retrievePropertyFilesByBundleName( String bundleName, PsiElement element) { final Project project = element.getProject(); return PropertiesReferenceManager.getInstance(project) .findPropertiesFiles( GlobalSearchScope.projectScope(project), bundleName, BundleNameEvaluator.DEFAULT); } } }; } } return PsiReference.EMPTY_ARRAY; }
@Override public void visitXmlAttribute(XmlAttribute attribute) { final XmlAttributeDescriptor descriptor = attribute.getDescriptor(); if (descriptor instanceof JavaFxStaticSetterAttributeDescriptor) { final PsiElement declaration = descriptor.getDeclaration(); if (declaration instanceof PsiMember) { appendClassName(((PsiMember) declaration).getContainingClass()); } } else if (descriptor instanceof JavaFxRootTagDescriptor.RootTagTypeAttributeDescriptor) { appendClassName(JavaFxPsiUtil.findPsiClass(attribute.getValue(), attribute)); } }
public static boolean isElementWithEmbeddedType( XmlTagImpl xml, final String typeName, final String typeNsPrefix) { final String localName = xml.getLocalName(); if (!(XmlUtil.XML_SCHEMA_URI.equals(xml.getNamespace()) && "element".equals(localName))) { return false; } final XmlAttribute nameAttr = getNameAttr(xml); if (nameAttr == null || nameAttr.getValue() == null) return false; final String localTypeName = XmlUtil.findLocalNameByQualifiedName(nameAttr.getValue()); final String prefix = XmlUtil.findPrefixByQualifiedName(nameAttr.getValue()); if (!typeName.equals(localTypeName) || !typeNsPrefix.equals(prefix)) { return false; } final XmlTag[] tags = xml.getSubTags(); for (XmlTag tag : tags) { if (isTypeElement((XmlTagImpl) tag)) { return true; } } return false; }
private static void inlineSingleTag( XmlTag includeTag, XmlTag includeParentTag, XmlTag layoutRootTag) { final Map<String, String> attributesToAdd = new HashMap<String, String>(); for (XmlAttribute attribute : includeTag.getAttributes()) { final String namespace = attribute.getNamespace(); if (SdkConstants.NS_RESOURCES.equals(namespace)) { attributesToAdd.put(attribute.getLocalName(), attribute.getValue()); } } final XmlTag newTag = (XmlTag) includeTag.replace(layoutRootTag.copy()); final List<XmlAttribute> toDelete = new ArrayList<XmlAttribute>(); for (XmlAttribute attribute : newTag.getAttributes()) { if (attribute.isNamespaceDeclaration()) { final String localName = attribute.getLocalName(); final String prefix = localName.equals(attribute.getName()) ? "" : localName; final String namespace = attribute.getValue(); if (includeParentTag != null && namespace.equals(includeParentTag.getNamespaceByPrefix(prefix))) { toDelete.add(attribute); } } } for (XmlAttribute attribute : toDelete) { attribute.delete(); } for (Map.Entry<String, String> entry : attributesToAdd.entrySet()) { final String localName = entry.getKey(); final String value = entry.getValue(); newTag.setAttribute(localName, SdkConstants.NS_RESOURCES, value); } CodeStyleManager.getInstance(newTag.getManager()).reformat(newTag); }
private static void collectDependencies( @Nullable XmlTag myTag, @NotNull XmlFile myFile, @NotNull Set<PsiFile> visited) { if (visited.contains(myFile)) return; visited.add(myFile); if (myTag == null) return; XmlTag[] tags = myTag.getSubTags(); for (final XmlTag tag : tags) { if (equalsToSchemaName(tag, INCLUDE_TAG_NAME) || equalsToSchemaName(tag, IMPORT_TAG_NAME)) { final XmlAttribute schemaLocation = tag.getAttribute("schemaLocation", null); if (schemaLocation != null) { final XmlFile xmlFile = XmlUtil.findNamespaceByLocation(myFile, schemaLocation.getValue()); addDependency(xmlFile, visited); } } else if (equalsToSchemaName(tag, REDEFINE_TAG_NAME)) { myRedefinedDescriptorsInProcessing.set(visited); try { final XmlFile file = getRedefinedElementDescriptorFile(tag); addDependency(file, visited); } finally { myRedefinedDescriptorsInProcessing.set(null); } } } final String schemaLocationDeclaration = myTag.getAttributeValue("schemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI); if (schemaLocationDeclaration != null) { final StringTokenizer tokenizer = new StringTokenizer(schemaLocationDeclaration); while (tokenizer.hasMoreTokens()) { final String uri = tokenizer.nextToken(); if (tokenizer.hasMoreTokens()) { PsiFile resourceLocation = ExternalResourceManager.getInstance() .getResourceLocation(tokenizer.nextToken(), myFile, null); if (resourceLocation == null && uri != null) resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(uri, myFile, null); if (resourceLocation instanceof XmlFile) addDependency((XmlFile) resourceLocation, visited); } } } }
@Override public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException { if (!FileModificationService.getInstance().preparePsiElementsForWrite(element)) return; final XmlAttribute attr = (XmlAttribute) element.getParent(); final String name = attr.getName(); final XmlAttributeDescriptor descriptor = attr.getDescriptor(); LOG.assertTrue(descriptor != null); String value = attr.getValue(); final PsiElement declaration = descriptor.getDeclaration(); if (declaration instanceof PsiField) { final PsiType fieldType = ((PsiField) declaration).getType(); final PsiType itemType = JavaGenericsUtil.getCollectionItemType(fieldType, declaration.getResolveScope()); if (itemType != null) { final String typeNode = itemType.getPresentableText(); JavaFxPsiUtil.insertImportWhenNeeded( (XmlFile) attr.getContainingFile(), typeNode, itemType.getCanonicalText()); final String[] vals = value.split(","); value = StringUtil.join( vals, new Function<String, String>() { @Override public String fun(String s) { return "<" + typeNode + " " + FxmlConstants.FX_VALUE + "=\"" + s.trim() + "\"/>"; } }, "\n"); } } final XmlTag childTag = XmlElementFactory.getInstance(project) .createTagFromText("<" + name + ">" + value + "</" + name + ">"); attr.getParent().add(childTag); attr.delete(); }
@Nullable private BidirectionalMap<String, String> computeNamespaceMap(PsiElement parent) { BidirectionalMap<String, String> map = null; if (hasNamespaceDeclarations()) { map = new BidirectionalMap<String, String>(); final XmlAttribute[] attributes = getAttributes(); for (final XmlAttribute attribute : attributes) { if (attribute.isNamespaceDeclaration()) { final String name = attribute.getName(); int splitIndex = name.indexOf(':'); final String value = getRealNs(attribute.getValue()); if (value != null) { if (splitIndex < 0) { map.put("", value); } else { map.put(XmlUtil.findLocalNameByQualifiedName(name), value); } } } } } if (parent instanceof XmlDocument) { final XmlExtension extension = XmlExtension.getExtensionByElement(parent); if (extension != null) { final String[][] defaultNamespace = extension.getNamespacesFromDocument((XmlDocument) parent, map != null); if (defaultNamespace != null) { if (map == null) { map = new BidirectionalMap<String, String>(); } for (final String[] prefix2ns : defaultNamespace) { map.put(prefix2ns[0], getRealNs(prefix2ns[1])); } } } } return map; }
@Nullable public String getInstalledPluginNameByPath(Project project, @NotNull VirtualFile pluginPath) { VirtualFile pluginXml = pluginPath.findChild("plugin.xml"); if (pluginXml == null) return null; PsiFile pluginXmlPsi = PsiManager.getInstance(project).findFile(pluginXml); if (!(pluginXmlPsi instanceof XmlFile)) return null; XmlTag rootTag = ((XmlFile) pluginXmlPsi).getRootTag(); if (rootTag == null || !"plugin".equals(rootTag.getName())) return null; XmlAttribute attrName = rootTag.getAttribute("name"); if (attrName == null) return null; String res = attrName.getValue(); if (res == null) return null; res = res.trim(); if (res.length() == 0) return null; return res; }
@NotNull private Map<String, CachedValue<XmlNSDescriptor>> computeNsDescriptorMap() { Map<String, CachedValue<XmlNSDescriptor>> map = null; // XSD aware attributes processing final String noNamespaceDeclaration = getAttributeValue("noNamespaceSchemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI); final String schemaLocationDeclaration = getAttributeValue("schemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI); if (noNamespaceDeclaration != null) { map = initializeSchema(XmlUtil.EMPTY_URI, null, noNamespaceDeclaration, map); } if (schemaLocationDeclaration != null) { final StringTokenizer tokenizer = new StringTokenizer(schemaLocationDeclaration); while (tokenizer.hasMoreTokens()) { final String uri = tokenizer.nextToken(); if (tokenizer.hasMoreTokens()) { map = initializeSchema(uri, null, tokenizer.nextToken(), map); } } } // namespace attributes processing (XSD declaration via ExternalResourceManager) if (hasNamespaceDeclarations()) { for (final XmlAttribute attribute : getAttributes()) { if (attribute.isNamespaceDeclaration()) { String ns = attribute.getValue(); if (ns == null) ns = XmlUtil.EMPTY_URI; ns = getRealNs(ns); if (map == null || !map.containsKey(ns)) { map = initializeSchema(ns, getNSVersion(ns, this), getNsLocation(ns), map); } } } } return map == null ? Collections.<String, CachedValue<XmlNSDescriptor>>emptyMap() : map; }
@Nullable private XmlAttributeDescriptor getAttributeImpl( String localName, String namespace, Set<XmlTag> visited) { if (myTag == null) return null; XmlNSDescriptorImpl nsDescriptor = (XmlNSDescriptorImpl) myTag.getNSDescriptor(namespace, true); if (nsDescriptor != this && nsDescriptor != null) { return nsDescriptor.getAttributeImpl(localName, namespace, visited); } if (visited == null) visited = new HashSet<XmlTag>(1); else if (visited.contains(myTag)) return null; visited.add(myTag); XmlTag[] tags = myTag.getSubTags(); for (XmlTag tag : tags) { if (equalsToSchemaName(tag, ATTRIBUTE_TAG_NAME)) { String name = tag.getAttributeValue("name"); if (name != null) { if (checkElementNameEquivalence(localName, namespace, name, tag)) { return createAttributeDescriptor(tag); } } } else if (equalsToSchemaName(tag, INCLUDE_TAG_NAME) || (equalsToSchemaName(tag, IMPORT_TAG_NAME) && namespace.equals(tag.getAttributeValue("namespace")))) { final XmlAttribute schemaLocation = tag.getAttribute("schemaLocation", null); if (schemaLocation != null) { final XmlFile xmlFile = XmlUtil.findNamespaceByLocation(myTag.getContainingFile(), schemaLocation.getValue()); if (xmlFile != null) { final XmlDocument includedDocument = xmlFile.getDocument(); if (includedDocument != null) { final PsiMetaData data = includedDocument.getMetaData(); if (data instanceof XmlNSDescriptorImpl) { final XmlAttributeDescriptor attributeDescriptor = ((XmlNSDescriptorImpl) data).getAttributeImpl(localName, namespace, visited); if (attributeDescriptor != null) { final CachedValue<XmlAttributeDescriptor> value = CachedValuesManager.getManager(includedDocument.getProject()) .createCachedValue( new CachedValueProvider<XmlAttributeDescriptor>() { public Result<XmlAttributeDescriptor> compute() { return new Result<XmlAttributeDescriptor>( attributeDescriptor, attributeDescriptor.getDependences()); } }, false); return value.getValue(); } } } } } } } return null; }
@Nullable public XmlElementDescriptor getElementDescriptor( String localName, String namespace, Set<XmlNSDescriptorImpl> visited, boolean reference) { if (visited.contains(this)) return null; final QNameKey pair = new QNameKey(namespace, localName); final CachedValue<XmlElementDescriptor> descriptor = myDescriptorsMap.get(pair); if (descriptor != null) { final XmlElementDescriptor value = descriptor.getValue(); if (value == null || value.getDeclaration().isValid()) return value; } final XmlTag rootTag = myTag; if (rootTag == null) return null; XmlTag[] tags = rootTag.getSubTags(); visited.add(this); for (final XmlTag tag : tags) { if (equalsToSchemaName(tag, ELEMENT_TAG_NAME)) { String name = tag.getAttributeValue("name"); if (name != null) { if (checkElementNameEquivalence(localName, namespace, name, tag)) { final CachedValue<XmlElementDescriptor> cachedValue = CachedValuesManager.getManager(tag.getProject()) .createCachedValue( new CachedValueProvider<XmlElementDescriptor>() { public Result<XmlElementDescriptor> compute() { final String name = tag.getAttributeValue("name"); if (name != null && !name.equals(pair.second)) { myDescriptorsMap.remove(pair); return new Result<XmlElementDescriptor>(null); } final XmlElementDescriptor xmlElementDescriptor = createElementDescriptor(tag); return new Result<XmlElementDescriptor>( xmlElementDescriptor, xmlElementDescriptor.getDependences()); } }, false); myDescriptorsMap.put(pair, cachedValue); return cachedValue.getValue(); } } } else if (equalsToSchemaName(tag, INCLUDE_TAG_NAME) || (reference && equalsToSchemaName(tag, IMPORT_TAG_NAME) && (namespace.equals(tag.getAttributeValue("namespace")) || namespace.length() == 0 && tag.getAttributeValue("namespace") == null))) { final XmlAttribute schemaLocation = tag.getAttribute("schemaLocation", null); if (schemaLocation != null) { final XmlFile xmlFile = XmlUtil.findNamespaceByLocation( rootTag.getContainingFile(), schemaLocation.getValue()); if (xmlFile != null) { final XmlDocument includedDocument = xmlFile.getDocument(); if (includedDocument != null) { final PsiMetaData data = includedDocument.getMetaData(); if (data instanceof XmlNSDescriptorImpl) { final XmlElementDescriptor elementDescriptor = ((XmlNSDescriptorImpl) data) .getElementDescriptor(localName, namespace, visited, reference); if (elementDescriptor != null) { // final CachedValue<XmlElementDescriptor> value = // includedDocument.getManager().getCachedValuesManager() // .createCachedValue(new CachedValueProvider<XmlElementDescriptor>() { // public Result<XmlElementDescriptor> compute() { // return new Result<XmlElementDescriptor>(elementDescriptor, // elementDescriptor.getDependences()); // } // }, false); // return value.getValue(); return elementDescriptor; } } } } } } else if (equalsToSchemaName(tag, REDEFINE_TAG_NAME)) { final XmlNSDescriptorImpl nsDescriptor = getRedefinedElementDescriptor(tag); if (nsDescriptor != null) { final XmlElementDescriptor xmlElementDescriptor = nsDescriptor.getElementDescriptor(localName, namespace, visited, reference); if (xmlElementDescriptor != null) return xmlElementDescriptor; } } } return null; }