/**
* Attributes.java
* Got from http://artho.com/webtools/java/index.shtml
*/
package app.astrosoft.html;
import java.util.*;
public class Attributes extends LinkedList {
public Attributes() {
super();
}
public Attributes(String attr) throws IllegalArgumentException {
super();
setAttributes(attr);
}
public Attributes(Attribute[] attrs) {
super();
for (int i = 0; i < attrs.length; i++) {
add(attrs[i]);
}
}
public Attributes(Attribute attr) {
super();
add(attr);
}
/**
* Set the value of attributes.
* @param str String with HTML attributes like:
* border="0" cellpadding="0" cellspacing="0"
*/
public void setAttributes(String str) throws IllegalArgumentException {
Attribute attribute = new Attribute();
final int START = 0;
// final int EOL = 1;
final int ERR = -1;
final int Attr = 2;
final int Val0 = 3;
final int Val1 = 4;
final int Value = 5;
final int QVal = 6;
// finite state machine for parsing
int state = START;
int prev = -1; // debug
int i = 0;
StringBuffer token = new StringBuffer();
while ((i <= str.length()) && (state != ERR)) {
char chr;
if (i < str.length())
chr = str.charAt(i);
else
chr = ' ';
i++;
prev = state;
switch(state) {
case START:
switch(chr) {
case ' ': break;
case '"': case '=':
state = ERR; break;
default: token.append(chr); state = Attr;
}
break;
case Attr:
switch(chr) {
case ' ':
attribute = new Attribute(token.toString());
state = Val0;
break;
case '=':
attribute = new Attribute(token.toString());
state = Val1;
break;
case '"':
state = ERR; break;
default: token.append(chr);
}
break;
case Val0:
switch(chr) {
case '=': state = Val1; break;
case ' ': break;
default:
this.add(attribute);
token = new StringBuffer();
token.append(chr);
state = Attr;
}
break;
case Val1:
token = new StringBuffer();
switch(chr) {
case '"': state = QVal; break;
case '=': state = ERR; break;
case ' ': break;
default:
token.append(chr);
state = Value;
break;
}
break;
case Value:
switch(chr) {
case ' ':
attribute.setValue(token.toString());
this.add(attribute);
token = new StringBuffer();
state = START;
break;
case '=': state = ERR; break;
default: token.append(chr);
}
break;
case QVal:
switch(chr) {
case '"':
attribute.setValue(token.toString());
this.add(attribute);
token = new StringBuffer();
state = START;
break;
default: token.append(chr);
}
break;
}
}
if ((i <= str.length()) || (state == ERR)) {
System.err.println("Parse error:");
System.err.println(str);
for (int j = 0; j < i; j++)
System.err.print(' ');
System.err.println('^');
throw new IllegalArgumentException("Parse error in state " +
Integer.toString(prev));
}
}
public String toString() {
StringBuffer out = new StringBuffer(" ");
ListIterator iterator = this.listIterator();
while (iterator.hasNext()) {
out.append(iterator.next().toString());
out.append(' ');
}
out.deleteCharAt(out.length() - 1);
return out.toString();
}
}