package jp.aonir.fuzzyxml.internal;
import jp.aonir.fuzzyxml.FuzzyXMLAttribute;
import jp.aonir.fuzzyxml.FuzzyXMLElement;
import jp.aonir.fuzzyxml.FuzzyXMLNode;
import org.objectstyle.wolips.wodclipse.core.util.WodHtmlUtils;
public class FuzzyXMLAttributeImpl extends AbstractFuzzyXMLNode implements FuzzyXMLAttribute {
private char _quote = '"';
private boolean _escape = true;
private String _namespace;
private String _name;
private String _value;
private String _rawValue;
private int _valueOffset;
private boolean _hasNestedTag;
public FuzzyXMLAttributeImpl(String namespace, String name) {
this(null, namespace, name, null, null, -1, -1, -1);
}
public FuzzyXMLAttributeImpl(String namespace, String name, String value, String rawValue) {
this(null, namespace, name, value, rawValue, -1, -1, -1);
setValue(value);
_rawValue = rawValue;
}
public FuzzyXMLAttributeImpl(FuzzyXMLNode parent, String namespace, String name, String value, String rawValue, int offset, int length, int valueOffset) {
super(parent, offset, length);
this._namespace = namespace;
this._name = name;
this._value = value;
this._rawValue = rawValue;
_valueOffset = valueOffset;
}
public void setHasNestedTag(boolean hasNestedTag) {
_hasNestedTag = hasNestedTag;
}
public boolean hasNestedTag() {
return _hasNestedTag;
}
public String getRawValue() {
return _rawValue;
}
public String getName() {
return _name;
}
public String getNamespace() {
return _namespace;
}
public int getNamespaceOffset() {
return getOffset() + 1;
}
public int getNamespaceLength() {
return _namespace != null ? _namespace.length() : 0;
}
public int getNameOffset() {
int nameOffset;
if (_namespace == null) {
nameOffset = getOffset() + 1;
}
else {
nameOffset = getNamespaceOffset() + getNamespaceLength() + 1;
}
return nameOffset;
}
public int getNameLength() {
return _name != null ? _name.length() : 0;
}
public int getValueOffset() {
return _valueOffset;
}
public int getValueLength() {
return _value != null ? _value.length() : 0;
}
public int getValueDataOffset() {
int offset = 0;
if (_value != null) {
offset = getValueOffset();
if (isQuoted()) {
offset ++;
}
}
return offset;
}
public int getValueDataLength() {
int length = 0;
if (_value != null) {
length = getValueLength();
}
return length;
}
public void setValue(String value) {
if (this._value == null) {
this._value = "";
}
int length = this._value.length();
this._value = (value == null) ? "" : value;
this._rawValue = this._value;
// �X�V�C�x���g��
FuzzyXMLDocumentImpl document = getDocument();
boolean html = (document == null) ? true : document.isHTML();
fireModifyEvent(toXMLString(new RenderContext(html)), getOffset(), getLength());
// �ʒu�����X�V
appendOffset((FuzzyXMLElement) getParentNode(), getOffset(), this._value.length() - length);
}
public String getValue() {
return _value;
}
public boolean isQuoted() {
return _quote != 0;
}
public char getQuoteCharacter() {
return _quote;
}
public void setQuoteCharacter(char c) {
_quote = c;
}
public void setEscape(boolean escape) {
this._escape = escape;
}
public boolean isEscape() {
return this._escape;
}
public String getNamespaceName() {
String attributeName = getName();
String namespace = getNamespace();
if (namespace != null && namespace.length() > 0) {
attributeName = namespace + ":" + attributeName;
}
return attributeName;
}
public String toDebugString() {
StringBuffer sb = new StringBuffer();
toDebugString(sb, 0);
return sb.toString();
}
public void toDebugString(StringBuffer buffer, int indent) {
for (int i = 0; i < indent; i ++) {
buffer.append(" ");
}
buffer.append(getName() + "=" + getValue());
}
public void toXMLString(RenderContext renderContext, StringBuffer xmlBuffer) {
boolean isHTML = renderContext.isHtml();
xmlBuffer.append(" ");
String attributeName = FuzzyXMLUtil.escape(getName(), isHTML);
String namespace = getNamespace();
if (namespace != null && namespace.length() > 0) {
attributeName = namespace + ":" + attributeName;
}
if (renderContext.isLowercaseAttributes()) {
FuzzyXMLNode parentNode = getParentNode();
boolean inlineTag = (parentNode instanceof FuzzyXMLElement && WodHtmlUtils.isInline(((FuzzyXMLElement)parentNode).getName()));
if (!inlineTag && FuzzyXMLUtil.isAllUppercase(attributeName)) {
attributeName = attributeName.toLowerCase();
}
}
xmlBuffer.append(attributeName);
if (renderContext.isSpacesAroundEquals()) {
xmlBuffer.append(" ");
}
xmlBuffer.append("=");
if (renderContext.isSpacesAroundEquals()) {
xmlBuffer.append(" ");
}
char quote = _quote;
if (renderContext.isAddMissingQuotes()) {
quote = '"';
}
if (quote != 0) {
xmlBuffer.append(quote);
}
// MS: Technically we want to escape everything BUT the nested tags, but just avoid it all for now
boolean hasNestedTag = hasNestedTag();
if (_escape && hasNestedTag) {
// Only do minimal XML escaping on the contents of attribute values
xmlBuffer.append(FuzzyXMLUtil.escape(_value, false));
}
else {
boolean inNestedTag = false;
String value = getValue();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (hasNestedTag && c == '<') {
inNestedTag = true;
}
else if (c == '>') {
inNestedTag = false;
}
else if (!inNestedTag && _quote == c) {
xmlBuffer.append('\\');
}
xmlBuffer.append(c);
}
}
if (quote != 0) {
xmlBuffer.append(quote);
}
}
@Override
public String toString() {
return "attr: " + getName() + "=" + getValue();
}
}