1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jmonit.reporting;
17
18 import java.io.ByteArrayOutputStream;
19 import java.io.PrintWriter;
20 import java.lang.reflect.Array;
21 import java.util.BitSet;
22 import java.util.Iterator;
23 import java.util.Locale;
24 import java.util.Map;
25
26 import org.jmonit.Monitor;
27
28
29
30
31 public class JSonRenderer
32 implements Renderer, Visitor
33 {
34 private PrintWriter writer;
35
36 public JSonRenderer( PrintWriter writer )
37 {
38 super();
39 this.writer = writer;
40 }
41
42 public void setLocale( Locale locale )
43 {
44
45 }
46
47
48
49
50
51
52 public Renderer createNew( PrintWriter writer )
53 {
54 return new JSonRenderer( writer );
55 }
56
57
58
59
60
61
62 public void render( Iterator<Visitable> iterator )
63 {
64 writer.print( "[" );
65 while ( iterator.hasNext() )
66 {
67 iterator.next().accept( this );
68 if ( iterator.hasNext() )
69 {
70 writer.write( "," );
71 }
72 }
73 writer.print( "]" );
74 }
75
76
77
78
79
80
81 public void visit( Monitor monitor )
82 {
83
84 }
85
86
87
88
89
90
91 public void visit( Map<String, Object> attributes )
92 {
93 writer.print( "{ " );
94 for ( Iterator<Map.Entry<String, Object>> iterator = attributes.entrySet().iterator(); iterator
95 .hasNext(); )
96 {
97 Map.Entry<String, Object> entry = iterator.next();
98 String key = entry.getKey();
99 Object value = entry.getValue();
100 if ( value instanceof Visitable )
101 {
102 writer.print( "\"" + key + "\" : " );
103 ( (Visitable) value ).accept( this );
104 }
105 else if ( value.getClass().isArray() )
106 {
107 writer.print( "\"" + key + "\" : [" );
108 int length = Array.getLength( value );
109 for ( int i = 0; i < length; )
110 {
111 Object element = Array.get( value, i++ );
112 writer.print( "\"" + sanitize( String.valueOf( element ) ) + "\"" );
113 if ( i < length )
114 {
115 writer.print( "," );
116 }
117 }
118 writer.print( "]" );
119 }
120 else
121 {
122 writer.print( "\"" + key + "\" : \"" + sanitize( String.valueOf( value ) ) + "\"" );
123 }
124 if ( iterator.hasNext() )
125 {
126 writer.print( "," );
127 }
128 }
129 writer.print( "}" );
130 }
131
132
133
134
135 private static final BitSet SAFE = new BitSet( 256 );
136
137
138 static
139 {
140
141 for ( int i = 'a'; i <= 'z'; i++ )
142 {
143 SAFE.set( i );
144 }
145 for ( int i = 'A'; i <= 'Z'; i++ )
146 {
147 SAFE.set( i );
148 }
149
150 for ( int i = '0'; i <= '9'; i++ )
151 {
152 SAFE.set( i );
153 }
154
155 SAFE.set( '-' );
156 SAFE.set( '_' );
157 SAFE.set( '.' );
158 SAFE.set( '*' );
159 SAFE.set( '~' );
160 }
161
162
163
164
165
166
167
168 private String sanitize( String string )
169 {
170 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
171 byte[] bytes = string.getBytes();
172 for ( int i = 0; i < bytes.length; i++ )
173 {
174 int b = bytes[i];
175 if ( b < 0 )
176 {
177 b = 256 + b;
178 }
179 if ( SAFE.get( b ) )
180 {
181 buffer.write( b );
182 }
183 else
184 {
185 buffer.write( '%' );
186 char hex1 = Character.toUpperCase( Character.forDigit( ( b >> 4 ) & 0xF, 16 ) );
187 char hex2 = Character.toUpperCase( Character.forDigit( b & 0xF, 16 ) );
188 buffer.write( hex1 );
189 buffer.write( hex2 );
190 }
191 }
192 return new String( buffer.toByteArray() );
193 }
194 }