| 1466 | 1 package goodjava.xml; | 
|  | 2 | 
|  | 3 import java.util.Map; | 
|  | 4 | 
|  | 5 | 
|  | 6 public final class XmlElement { | 
|  | 7 	public final String name; | 
|  | 8 	public final Map<String,String> attributes; | 
| 1790 | 9 	private Object content = null; | 
| 1791 | 10 	private XmlElement parent = null; | 
| 1466 | 11 | 
| 1468 | 12 	public XmlElement(String name,Map<String,String> attributes) { | 
|  | 13 		this.name = name; | 
|  | 14 		this.attributes = attributes; | 
|  | 15 		this.content = null; | 
|  | 16 	} | 
|  | 17 | 
| 1791 | 18 	public XmlElement getParent() { | 
|  | 19 		return parent; | 
|  | 20 	} | 
|  | 21 | 
| 1790 | 22 	public Object getContent() { | 
|  | 23 		return content; | 
|  | 24 	} | 
|  | 25 | 
|  | 26 	public void removeContent() { | 
|  | 27 		content = null; | 
|  | 28 	} | 
|  | 29 | 
|  | 30 	public void setContent(String content) { | 
| 1468 | 31 		if( content == null ) | 
| 1810 | 32 			throw new IllegalArgumentException("content of '"+name+"' can't be null"); | 
| 1466 | 33 		this.content = content; | 
|  | 34 	} | 
|  | 35 | 
| 1790 | 36 	public void setContent(XmlElement[] content) { | 
| 1468 | 37 		if( content == null ) | 
| 1810 | 38 			throw new IllegalArgumentException("content of '"+name+"' can't be null"); | 
| 1466 | 39 		this.content = content; | 
| 1791 | 40 		for( XmlElement el : content ) { | 
|  | 41 			el.parent = this; | 
|  | 42 		} | 
| 1466 | 43 	} | 
|  | 44 | 
| 1790 | 45 	@Override public String toString() { | 
| 1466 | 46 		StringBuilder sb = new StringBuilder(); | 
|  | 47 		toString(sb,0); | 
|  | 48 		return sb.toString(); | 
|  | 49 	} | 
|  | 50 | 
| 1790 | 51 	void toString(StringBuilder sb,int indented) { | 
| 1466 | 52 		indent(sb,indented); | 
|  | 53 		sb.append( '<' ); | 
|  | 54 		sb.append( name ); | 
|  | 55 		for( Map.Entry<String,String> attribute : attributes.entrySet() ) { | 
|  | 56 			sb.append( ' ' ); | 
|  | 57 			sb.append( attribute.getKey() ); | 
|  | 58 			sb.append( "=\"" ); | 
| 1793 | 59 			sb.append( encodeAttr(attribute.getValue()) ); | 
| 1466 | 60 			sb.append( '"' ); | 
|  | 61 		} | 
| 1468 | 62 		if( content == null ) { | 
|  | 63 			sb.append( "/>\n" ); | 
|  | 64 		} else if( content instanceof String ) { | 
|  | 65 			sb.append( '>' ); | 
| 1466 | 66 			String s = (String)content; | 
| 1468 | 67 			sb.append( encode(s) ); | 
|  | 68 			closeTag(sb,name); | 
| 1467 | 69 		} else { | 
| 1468 | 70 			sb.append( '>' ); | 
| 1466 | 71 			XmlElement[] elements = (XmlElement[])content; | 
|  | 72 			sb.append( '\n' ); | 
|  | 73 			for( XmlElement element : elements ) { | 
|  | 74 				element.toString(sb,indented+1); | 
|  | 75 			} | 
|  | 76 			indent(sb,indented); | 
| 1468 | 77 			closeTag(sb,name); | 
| 1467 | 78 		} | 
| 1468 | 79 	} | 
|  | 80 | 
|  | 81 	private static void closeTag(StringBuilder sb,String name) { | 
| 1466 | 82 		sb.append( "</" ); | 
|  | 83 		sb.append( name ); | 
|  | 84 		sb.append( ">\n" ); | 
|  | 85 	} | 
|  | 86 | 
| 1467 | 87 	private static void indent(StringBuilder sb,int indented) { | 
| 1466 | 88 		for( int i=0; i<indented; i++ ) { | 
|  | 89 			sb.append('\t'); | 
|  | 90 		} | 
|  | 91 	} | 
|  | 92 | 
| 1469 | 93 	public static String encode(String s) { | 
| 1468 | 94 		final char[] a = s.toCharArray(); | 
|  | 95 		StringBuilder buf = new StringBuilder(); | 
| 1469 | 96 		for( char c : a ) { | 
| 1468 | 97 			switch(c) { | 
|  | 98 			case '&': | 
|  | 99 				buf.append("&"); | 
|  | 100 				break; | 
|  | 101 			case '<': | 
|  | 102 				buf.append("<"); | 
|  | 103 				break; | 
|  | 104 			case '>': | 
|  | 105 				buf.append(">"); | 
|  | 106 				break; | 
|  | 107 			case '"': | 
|  | 108 				buf.append("""); | 
|  | 109 				break; | 
| 1469 | 110 			case '\'': | 
|  | 111 				buf.append("'"); | 
|  | 112 				break; | 
| 1793 | 113 			default: | 
|  | 114 				buf.append(c); | 
|  | 115 			} | 
|  | 116 		} | 
|  | 117 		return buf.toString(); | 
|  | 118 	} | 
|  | 119 | 
|  | 120 	public static String encodeAttr(String s) { | 
|  | 121 		final char[] a = s.toCharArray(); | 
|  | 122 		StringBuilder buf = new StringBuilder(); | 
|  | 123 		for( char c : a ) { | 
|  | 124 			switch(c) { | 
|  | 125 			case '&': | 
|  | 126 				buf.append("&"); | 
|  | 127 				break; | 
|  | 128 			case '<': | 
|  | 129 				buf.append("<"); | 
|  | 130 				break; | 
|  | 131 			case '>': | 
|  | 132 				buf.append(">"); | 
|  | 133 				break; | 
|  | 134 			case '"': | 
|  | 135 				buf.append("""); | 
|  | 136 				break; | 
|  | 137 			case '\'': | 
|  | 138 				buf.append("'"); | 
|  | 139 				break; | 
| 1790 | 140 			case '\n': | 
|  | 141 				buf.append("
"); | 
|  | 142 				break; | 
|  | 143 			case '\r': | 
|  | 144 				buf.append("
"); | 
|  | 145 				break; | 
| 1468 | 146 			default: | 
|  | 147 				buf.append(c); | 
|  | 148 			} | 
|  | 149 		} | 
|  | 150 		return buf.toString(); | 
|  | 151 	} | 
|  | 152 | 
| 1466 | 153 } |