@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); }
private int getAttributeValueStartOffset() { final XmlAttribute attr = getAttribute(); final XmlAttributeValue valueElement = attr.getValueElement(); return (valueElement == null) ? attr.getTextRange().getEndOffset() + 1 : valueElement.getTextRange().getStartOffset() + 1; }
@NotNull public XPathType getExpectedType(XPathExpression expr) { final XmlTag tag = PsiTreeUtil.getContextOfType(expr, XmlTag.class, true); if (tag != null && XsltSupport.isXsltTag(tag)) { final XsltElement element = XsltElementFactory.getInstance().wrapElement(tag, XsltElement.class); if (element instanceof XsltVariable) { return ((XsltVariable) element).getType(); } else { final XmlAttribute attr = PsiTreeUtil.getContextOfType(expr, XmlAttribute.class, true); if (attr != null) { if (element instanceof XsltWithParam) { final XmlAttribute nameAttr = tag.getAttribute("name", null); if (nameAttr != null) { final XmlAttributeValue valueElement = nameAttr.getValueElement(); if (valueElement != null) { final PsiReference[] references = valueElement.getReferences(); for (PsiReference reference : references) { final PsiElement psiElement = reference.resolve(); if (psiElement instanceof XsltVariable) { return ((XsltVariable) psiElement).getType(); } } } } } else { final String name = attr.getName(); return getTypeForTag(tag, name); } } } } return XPathType.UNKNOWN; }
private void checkDuplicateAttribute(XmlTag tag, final XmlAttribute attribute) { if (skipValidation(tag)) { return; } final XmlAttribute[] attributes = tag.getAttributes(); final PsiFile containingFile = tag.getContainingFile(); final XmlExtension extension = containingFile instanceof XmlFile ? XmlExtension.getExtension(containingFile) : XmlExtension.DEFAULT_EXTENSION; for (XmlAttribute tagAttribute : attributes) { ProgressManager.checkCanceled(); if (attribute != tagAttribute && Comparing.strEqual(attribute.getName(), tagAttribute.getName())) { final String localName = attribute.getLocalName(); if (extension.canBeDuplicated(tagAttribute)) continue; // multiple import attributes are allowed in jsp directive HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo( getTagProblemInfoType(tag), XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild( SourceTreeToPsiMap.psiElementToTree(attribute)), XmlErrorMessages.message("duplicate.attribute", localName)); addToResults(highlightInfo); IntentionAction intentionAction = new RemoveAttributeIntentionFix(localName, attribute); QuickFixAction.registerQuickFixAction(highlightInfo, intentionAction); } } }
public PsiFile resolve() { final PsiFile referencedFile = getReferencedFile(); if (referencedFile != null) { return referencedFile; } if (myPsiFile != null) { final PsiElement psiElement = myPsiFile.findElementAt(myLinkInfo.offset); if (psiElement != null) { final PsiElement parent = psiElement.getParent(); if (parent instanceof XmlTag) { final XmlAttribute attribute = ((XmlTag) parent).getAttribute(HREF_ATTR); if (attribute != null) { final XmlAttributeValue value = attribute.getValueElement(); if (value != null) { final PsiReference[] references = value.getReferences(); for (PsiReference reference : references) { final PsiElement element = reference.resolve(); if (element instanceof PsiFile) { return (PsiFile) element; } } } } } } } return null; }
public static List<DomElement> getDefinedChildren( @NotNull final DomElement parent, final boolean tags, final boolean attributes) { if (parent instanceof MergedObject) { final SmartList<DomElement> result = new SmartList<>(); parent.acceptChildren( new DomElementVisitor() { @Override public void visitDomElement(final DomElement element) { if (hasXml(element)) { result.add(element); } } }); return result; } ProgressManager.checkCanceled(); if (parent instanceof GenericAttributeValue) return Collections.emptyList(); if (parent instanceof DomFileElement) { final DomFileElement element = (DomFileElement) parent; return tags ? Arrays.asList(element.getRootElement()) : Collections.<DomElement>emptyList(); } final XmlElement xmlElement = parent.getXmlElement(); if (xmlElement instanceof XmlTag) { XmlTag tag = (XmlTag) xmlElement; final DomManager domManager = parent.getManager(); final SmartList<DomElement> result = new SmartList<>(); if (attributes) { for (final XmlAttribute attribute : tag.getAttributes()) { if (!attribute.isValid()) { LOG.error("Invalid attr: parent.valid=" + tag.isValid()); continue; } GenericAttributeValue element = domManager.getDomElement(attribute); if (checkHasXml(attribute, element)) { ContainerUtil.addIfNotNull(result, element); } } } if (tags) { for (final XmlTag subTag : tag.getSubTags()) { if (!subTag.isValid()) { LOG.error("Invalid subtag: parent.valid=" + tag.isValid()); continue; } DomElement element = domManager.getDomElement(subTag); if (checkHasXml(subTag, element)) { ContainerUtil.addIfNotNull(result, element); } } } return result; } return Collections.emptyList(); }
@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 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)); }
@Override public int getOffsetInHost(final int offsetInDecoded, @NotNull final TextRange rangeInsideHost) { TextRange valueTextRange = myXmlAttribute.getValueTextRange(); int displayStart = myXmlAttribute.physicalToDisplay(rangeInsideHost.getStartOffset()); int dp = myXmlAttribute.displayToPhysical( offsetInDecoded + displayStart - valueTextRange.getStartOffset()); if (dp == -1) return -1; return dp + valueTextRange.getStartOffset(); }
@Nullable protected String getValue() { final XmlAttribute attribute = (XmlAttribute) getXmlElement(); if (attribute != null) { final XmlAttributeValue value = attribute.getValueElement(); if (value != null && value.getTextLength() >= 2) { return attribute.getDisplayValue(); } } return null; }
@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)); } }
private static boolean canBeExtracted(@NotNull XmlAttribute attribute) { if (!(SdkConstants.NS_RESOURCES.equals(attribute.getNamespace()))) { return false; } final String name = attribute.getLocalName(); if (ArrayUtil.find(NON_EXTRACTABLE_ATTRIBUTES, name) >= 0) { return false; } if (name.startsWith(AndroidDomUtil.ATTR_STYLE)) { return false; } return true; }
private static boolean isHrefScripted(final XmlTag tag) { final XmlAttribute attribute = tag.getAttribute(HREF_ATTR); if (attribute != null) { final XmlAttributeValue value = attribute.getValueElement(); if (value != null) { if (PsiTreeUtil.getChildOfType(value, OuterLanguageElement.class) != null) { return true; } } } return false; }
@Nullable private static String getAttributeValue(final XmlTag tag, final String attrName) { final XmlAttribute attribute = tag.getAttribute(attrName); if (attribute != null) { final XmlAttributeValue value = attribute.getValueElement(); if (value != null) { if (PsiTreeUtil.getChildOfType(value, OuterLanguageElement.class) == null) { return value.getValue(); } } } return null; }
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); } } } }
@Nullable public static PsiFile resolveFile(XmlAttribute location, PsiFile baseFile) { if (location == null) return null; final XmlAttributeValue valueElement = location.getValueElement(); if (valueElement == null) return null; // prefer direct relative path final String value = valueElement.getValue(); final PsiFile file = resolveFile(value, baseFile); if (file != baseFile && file instanceof XmlFile) { return file; } final PsiReference[] references = valueElement.getReferences(); for (PsiReference reference : references) { final PsiElement target = reference.resolve(); if (target == null && reference instanceof PsiPolyVariantReference) { final ResolveResult[] results = ((PsiPolyVariantReference) reference).multiResolve(false); for (ResolveResult result : results) { if (result.isValidResult()) { // TODO: how to weigh/prioritize the results? final PsiElement element = result.getElement(); if (element != baseFile && element instanceof XmlFile) { return (PsiFile) target; } } } } else if (target != baseFile && target instanceof XmlFile) { return (PsiFile) target; } } return null; }
protected void checkAttribute( @NotNull final XmlAttribute attribute, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) { final XmlTag tag = attribute.getParent(); if (tag instanceof HtmlTag) { XmlElementDescriptor elementDescriptor = tag.getDescriptor(); if (elementDescriptor == null || elementDescriptor instanceof AnyXmlElementDescriptor) { return; } XmlAttributeDescriptor attributeDescriptor = elementDescriptor.getAttributeDescriptor(attribute); final String name = attribute.getName(); if (attributeDescriptor == null && !attribute.isNamespaceDeclaration()) { if (!XmlUtil.attributeFromTemplateFramework(name, tag) && (!isCustomValuesEnabled() || !isCustomValue(name))) { final ASTNode node = attribute.getNode(); assert node != null; final PsiElement nameElement = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(node).getPsi(); boolean maySwitchToHtml5 = HtmlUtil.isCustomHtml5Attribute(name) && !HtmlUtil.hasNonHtml5Doctype(tag); LocalQuickFix[] quickfixes = new LocalQuickFix[maySwitchToHtml5 ? 3 : 2]; quickfixes[0] = new AddCustomTagOrAttributeIntentionAction( getShortName(), name, XmlEntitiesInspection.UNKNOWN_ATTRIBUTE); quickfixes[1] = new RemoveAttributeIntentionAction(name); if (maySwitchToHtml5) { quickfixes[2] = new SwitchToHtml5WithHighPriorityAction(); } holder.registerProblem( nameElement, XmlErrorMessages.message("attribute.is.not.allowed.here", name), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, quickfixes); } } } }
@Nullable public XmlAttribute getAttribute(String qname) { if (qname == null) return null; final XmlAttribute[] attributes = getAttributes(); final boolean caseSensitive = isCaseSensitive(); for (final XmlAttribute attribute : attributes) { final LeafElement attrNameElement = (LeafElement) XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(attribute.getNode()); if (attrNameElement != null && (caseSensitive && Comparing.equal(attrNameElement.getChars(), qname) || !caseSensitive && Comparing.equal(attrNameElement.getChars(), qname, false))) { return attribute; } } return null; }
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; }
public XmlAttribute setAttribute(String qname, String value) throws IncorrectOperationException { final XmlAttribute attribute = getAttribute(qname); if (attribute != null) { if (value == null) { deleteChildInternal(attribute.getNode()); return null; } attribute.setValue(value); return attribute; } else if (value == null) { return null; } else { PsiElement xmlAttribute = add(XmlElementFactory.getInstance(getProject()).createXmlAttribute(qname, value)); while (!(xmlAttribute instanceof XmlAttribute)) xmlAttribute = xmlAttribute.getNextSibling(); return (XmlAttribute) xmlAttribute; } }
public static String getAttributeName(XmlAttribute attribute) { if (attribute != null) { for (PsiElement child : attribute.getChildren()) { if (XmlHelper.isAttributeName(child)) { return child.getText(); } } } return null; }
@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; }
private static void replaceElements(XmlTag tag, TemplateBuilder builder) { for (XmlAttribute attribute : tag.getAttributes()) { XmlAttributeValue value = attribute.getValueElement(); if (value != null) { builder.replaceElement(value, TextRange.from(1, 0), new MacroCallNode(new CompleteMacro())); } } if ("<".equals(tag.getText())) { builder.replaceElement( tag, TextRange.from(1, 0), new MacroCallNode(new CompleteSmartMacro())); } else if (tag.getSubTags().length == 0) { int i = tag.getText().indexOf("></"); if (i > 0) { builder.replaceElement( tag, TextRange.from(i + 1, 0), new MacroCallNode(new CompleteMacro())); } } for (XmlTag subTag : tag.getSubTags()) { replaceElements(subTag, builder); } }
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; }
@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; }
public PsiFile[] getRelatedFiles(final XPathFile file) { final XmlAttribute attribute = PsiTreeUtil.getContextOfType(file, XmlAttribute.class, false); assert attribute != null; final PsiFile psiFile = attribute.getContainingFile(); assert psiFile != null; final List<PsiFile> files = new ArrayList<PsiFile>(); psiFile.accept( new XmlRecursiveElementVisitor() { @Override public void visitXmlAttribute(XmlAttribute attribute) { final PsiFile[] _files = XsltSupport.getFiles(attribute); for (PsiFile _file : _files) { if (_file != file) files.add(_file); } } }); return PsiUtilCore.toPsiFileArray(files); }
@Override public boolean decode(@NotNull final TextRange rangeInsideHost, @NotNull StringBuilder outChars) { ProperTextRange.assertProperRange(rangeInsideHost); TextRange valueTextRange = myXmlAttribute.getValueTextRange(); int startInDecoded = myXmlAttribute.physicalToDisplay( rangeInsideHost.getStartOffset() - valueTextRange.getStartOffset()); int endInDecoded = myXmlAttribute.physicalToDisplay( rangeInsideHost.getEndOffset() - valueTextRange.getStartOffset()); String displayValue = myXmlAttribute.getDisplayValue(); // todo investigate IIOB http://www.jetbrains.net/jira/browse/IDEADEV-16796 startInDecoded = startInDecoded < 0 ? 0 : startInDecoded > displayValue.length() ? displayValue.length() : startInDecoded; endInDecoded = endInDecoded < 0 ? 0 : endInDecoded > displayValue.length() ? displayValue.length() : endInDecoded; if (startInDecoded > endInDecoded) endInDecoded = startInDecoded; outChars.append(displayValue, startInDecoded, endInDecoded); return true; }
@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 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(); }