blob: 32a2239dd3a1d93d74b4ac28d49621c9ae88f22c [file] [log] [blame]
/*
* Copyright 2006 Sascha Weinreuter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.intellij.plugins.intelliLang.inject.config;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import org.intellij.plugins.intelliLang.util.StringMatcher;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import static org.intellij.plugins.intelliLang.inject.InjectorUtils.appendStringPattern;
public class XmlAttributeInjection extends AbstractTagInjection {
@NotNull @NonNls
private StringMatcher myAttributeNameMatcher = StringMatcher.NONE;
@NotNull @NonNls
private String myAttributeNamespace = "";
@NotNull
public String getAttributeName() {
return myAttributeNameMatcher.getPattern();
}
public void setAttributeName(@NotNull String attributeName) {
myAttributeNameMatcher = StringMatcher.create(attributeName);
}
@NotNull
public String getAttributeNamespace() {
return myAttributeNamespace;
}
public void setAttributeNamespace(@NotNull String attributeNamespace) {
myAttributeNamespace = attributeNamespace;
}
public boolean isApplicable(@NotNull XmlAttributeValue value) {
final PsiElement element = value.getParent();
return element instanceof XmlAttribute && matches((XmlAttribute)element);
}
public String getGeneratedName() {
final String tag = getTagName();
final String attributeName = getAttributeName();
if (!attributeName.equals(StringMatcher.NONE.getPattern())) {
if (tag.length() > 0) {
return tag + "/@" + (attributeName.length() > 0 ? attributeName : "*");
}
else {
return "*/@" + (attributeName.length() > 0 ? attributeName : "*");
}
}
return attributeName;
}
@Override
public void generatePlaces() {
if (StringUtil.isEmpty(getDisplayName())) setDisplayName(getGeneratedName());
setInjectionPlaces(new InjectionPlace(getCompiler().createElementPattern(getPatternString(this), getDisplayName()), true));
}
private boolean matches(@NotNull XmlAttribute attr) {
// mind IDEA-5206
final boolean b = myAttributeNameMatcher.matches(attr.getLocalName()) &&
(attr.getName().indexOf(':') == -1 || myAttributeNamespace.equals(attr.getNamespace())) &&
matches(attr.getParent());
return b && matchXPath(attr);
}
@Override
public XmlAttributeInjection copy() {
return new XmlAttributeInjection().copyFrom(this);
}
@Override
public XmlAttributeInjection copyFrom(@NotNull BaseInjection o) {
super.copyFrom(o);
if (o instanceof XmlAttributeInjection) {
XmlAttributeInjection other = (XmlAttributeInjection)o;
setApplyToSubTags(other.isApplyToSubTags());
setAttributeName(other.getAttributeName());
setAttributeNamespace(other.getAttributeNamespace());
}
return this;
}
@SuppressWarnings({"RedundantIfStatement"})
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
final XmlAttributeInjection that = (XmlAttributeInjection)o;
if (!myAttributeNameMatcher.getPattern().equals(that.myAttributeNameMatcher.getPattern())) return false;
if (!myAttributeNamespace.equals(that.myAttributeNamespace)) return false;
return true;
}
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myAttributeNameMatcher.getPattern().hashCode();
result = 31 * result + myAttributeNamespace.hashCode();
return result;
}
public static String getPatternString(final XmlAttributeInjection injection) {
final String name = injection.getAttributeName();
final String namespace = injection.getAttributeNamespace();
final StringBuilder result = new StringBuilder("xmlAttribute()");
if (StringUtil.isNotEmpty(name)) appendStringPattern(result, ".withLocalName(", name, ")");
if (StringUtil.isNotEmpty(namespace)) appendStringPattern(result, ".withNamespace(", namespace, ")");
if (StringUtil.isNotEmpty(injection.getTagName()) || StringUtil.isNotEmpty(injection.getTagNamespace())) {
result.append(".").append(injection.isApplyToSubTags() ? "inside" : "withParent").append("(")
.append(XmlTagInjection.getPatternString(injection)).append(")");
}
return result.toString();
}
}