1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
package scala.xml;
import scala.xml.javaAdapter.Map ;
import scala.xml.javaAdapter.HashMap ;
/** Generic.load( <fileName> ) will load the xml document from file and
* create a tree with scala.Labelled, PCDATA and scala.Symbol objects.
* Text can appear within PCDATA at the leaves.
*/
object Generic {
// utility functions
def iterToList[ a ]( iter:java.util.Iterator ):List[a] =
if( !iter.hasNext() )
Nil
else
(iter.next().asInstanceOf[ a ])::iterToList( iter ) ;
def mapToMap[a,b]( map:java.util.Map ):Map[a,b] = {
val keys:java.util.Iterator = map.keySet().iterator();
val res = new HashMap[a,b] ;
def iterToMap:Unit =
if( keys.hasNext() ) {
val key = keys.next();
val value = map.get( key ).asInstanceOf[ b ];
res.put( key.asInstanceOf[ a ], value.asInstanceOf[ b ]);
iterToMap
} else
() ;
iterToMap;
res
}
def toXML( attrib:Map[ String, String ] ):String = {
def iterate( keys:Iterator[String] ) =
if( keys.hasNext ) {
val key = keys.next;
" " + key + "=\"" + attrib.get( key ) + "\"";
} else {
""
}
if( attrib != null ) iterate( attrib.keys.elements ) else "";
}
// attributes
trait Attribbed {
// only CDATA / String attributes for now
def attribs : Map[String,String] ;
}
// functions for generic xml loading, saving
def load( filename:String ):Labelled = {
val b = new GenericFactoryAdapter().loadXML( filename );
b.asInstanceOf[Labelled]
};
def save( filename:String, doc:Any ):Unit = {
import java.io.{FileOutputStream,Writer};
import java.nio.channels.{Channels,FileChannel};
def toXML( xs: List[Any], fc:Writer ):Unit = xs match {
case _::ys =>
toXML( xs.head, fc );
toXML( ys, fc );
case _ => ()
}
def toXML( doc: Any, fc:Writer ):Unit = doc match {
case PCDATA( s ) =>
fc.write( (doc.asInstanceOf[ PCDATA ]).toXML );
case Labelled( Symbol( tag ), xs ) =>
fc.write( "<" );
fc.write( tag );
fc.write( Generic.toXML(( doc.asInstanceOf[ Attribbed ])
.attribs ));
fc.write( ">" );
toXML( xs, fc );
fc.write( "</" );
fc.write( tag );
fc.write( ">" );
}
val fos = new FileOutputStream( filename );
val w = Channels.newWriter( fos.getChannel(), "ISO-8859-1" );
toXML( doc, w );
w.close();
fos.close();
}
class GenericFactoryAdapter extends FactoryAdapter() {
def elementContainsText( name:java.lang.String ):boolean = true;
// default behaviour is hash-consing
val cache = new HashMap();
def createElement( elemName: String,
attrs: java.util.Map,
children: java.util.Iterator ):scala.Object = {
val el = new Labelled( Symbol( elemName ),
Generic.iterToList[ Any ]( children ))
with Attribbed {
def attribs = Generic.mapToMap[String,String]( attrs );
};
val el_cache = cache.get( el.asInstanceOf[scala.All])
.asInstanceOf[scala.Object];
if ( el_cache != null ) {
System.err.println("[using cached elem!]");
el_cache
} else {
cache.put( el.asInstanceOf[scala.All], el.asInstanceOf[scala.All] );
el
}
}
def createPCDATA( text:String ):scala.Object = {
new PCDATA( text );
};
} // GenericFactoryAdapter
}
|