simcha-mappum 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,193 @@
1
+ module Mappum
2
+ module MapServer
3
+ class Graph
4
+ attr_reader :edge_maps
5
+ def initialize(map)
6
+ @map = map
7
+ @root = []
8
+ @struct_from = StrTree.new(nil,0,@root)
9
+ @struct_from.name = "struct1"
10
+ @struct_to = StrTree.new(nil,0,@root)
11
+ @struct_to.name = "struct2"
12
+ @edges = []
13
+ @edge_maps = {}
14
+ init(@map,@struct_from, @struct_to)
15
+ end
16
+ def getSvg
17
+ cmd = "dot"
18
+ format = "svg"
19
+ xCmd = "#{cmd} -T#{format}"
20
+ puts dot = getDot
21
+ f = IO.popen( xCmd ,"r+")
22
+ f.print(dot)
23
+ f.close_write
24
+ return f
25
+ end
26
+ def getPng
27
+ cmd = "dot"
28
+ format = "png"
29
+ xCmd = "#{cmd} -T#{format}"
30
+ dot = getDot
31
+ f = IO.popen( xCmd ,"r+")
32
+ f.print(dot)
33
+ f.close_write
34
+ return f
35
+ end
36
+ def getDot
37
+ str1 = makeStruct(@struct_from)
38
+ str2 = makeStruct(@struct_to)
39
+ edge = @edges.join
40
+ return <<DOT
41
+ digraph structs { node [shape=plaintext]; rankdir=LR; nodesep=0.1;
42
+ struct1 [
43
+ label=<
44
+ #{str1}
45
+ >
46
+ ];
47
+ struct2 [
48
+ label=<
49
+ #{str2}
50
+ >
51
+ ];
52
+ #{@root.collect { |struct| struct.line}}
53
+ #{edge}
54
+
55
+ }
56
+ DOT
57
+ end
58
+
59
+ private
60
+
61
+ def makeStruct(struct_tree)
62
+ str = struct_tree.line || ""
63
+ unless struct_tree.children.nil? or struct_tree.children.empty?
64
+ str += "<TR><TD></TD> <TD CELLPADDING=\"1\">" unless struct_tree.parent.nil?
65
+ str += "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" BGCOLOR=\"cornsilk2\">\n"
66
+ st = struct_tree.children.collect { |child| makeStruct(child)}
67
+ st.uniq!
68
+ str += st.join + "</TABLE>"
69
+ str += "</TD></TR>\n" unless struct_tree.parent.nil?
70
+ end
71
+ return str
72
+ end
73
+ def init(map, struct_from, struct_to)
74
+ if map.normalized?
75
+ map_from, map_to = map.from, map.to
76
+ else
77
+ map_from, map_to = map.left, map.right
78
+ end
79
+ to_name, to_path, level_to = get_name_and_path(map_to)
80
+ from_name, from_path, level_from = get_name_and_path(map_from)
81
+
82
+ str_from = StrTree.new(struct_from,level_from, @root)
83
+ unless from_name.nil?
84
+ if level_from > -1
85
+ str_from.line = "<TR> <TD COLSPAN=\"2\" PORT=\"#{from_path}\">#{from_name}</TD></TR>\n"
86
+ else
87
+ str_from.line = "#{from_path} [ label = <\"#{from_name}\">];\n"
88
+ end
89
+ end
90
+ str_to = StrTree.new(struct_to,level_to,@root)
91
+ unless to_name.nil?
92
+ if level_to > -1
93
+ str_to.line ="<TR> <TD COLSPAN=\"2\" PORT=\"#{to_path}\">#{to_name}</TD></TR>\n"
94
+ else
95
+ str_to.line = "#{to_path} [ label = <\"#{to_name}\">];\n"
96
+ end
97
+ end
98
+ maps = []
99
+ if map.normalized?
100
+ maps = map.maps
101
+ else
102
+ maps = map.bidi_maps
103
+ end
104
+
105
+
106
+ unless maps.empty?
107
+ maps.each do |sub_map|
108
+ if(map.normalized? or sub_map.left.parent == map_from or
109
+ sub_map.right.parent == map_to)
110
+
111
+ init(sub_map, str_from, str_to)
112
+ else
113
+ init(sub_map, str_to, str_from)
114
+ end
115
+ end
116
+ else
117
+ # as option? labelfloat=true
118
+ from_ref = "#{str_from.root.name}:#{from_path}" if level_from > -1
119
+ to_ref = "#{str_to.root.name}:#{to_path}" if level_to > -1
120
+ from_ref ||= from_path
121
+ to_ref ||= to_path
122
+ edge = "#{from_ref} -> #{to_ref} ["
123
+ if map.normalized?
124
+ edge += " arrowtail = none tooltip=\"#{from_name} >> #{to_name}\" "
125
+ else
126
+ edge += " arrowtail = vee tooltip=\"#{from_name} <=> #{to_name}\" "
127
+ end
128
+ edge += " arrowhead = vee URL=\"##{@edges.size+1}\" fontsize=10 "
129
+ unless map.simple?
130
+ edge += " label=\"#{@edges.size+1}\" labeltooltip = \"#{@edges.size+1}: #{from_name} >> #{to_name}\""
131
+ end
132
+ color = "black"
133
+ color = "blue" if level_to == -1 or level_from == -1
134
+ edge += " minlen=\"3\" color=\"#{color}\"];\n"
135
+
136
+ @edges << edge
137
+ unless map.simple?
138
+ @edge_maps[@edges.size] = map
139
+ end
140
+ end
141
+
142
+ end
143
+ def get_name_and_path(element, level = 0)
144
+ #on non filed elements
145
+ if element.kind_of?(Function)
146
+ return "Function", "c#{element.__id__.abs}", -1
147
+ end
148
+ if element.kind_of?(Constant)
149
+ return element.value.to_s, "c#{element.__id__.abs}", -1
150
+ end
151
+
152
+ name = element.name
153
+ if element.parent.nil?
154
+ #root element
155
+ name ||= element.clazz.to_s
156
+ else
157
+ level = level + 1 if name.nil?
158
+ pname, path, level = get_name_and_path(element.parent, level)
159
+ end
160
+ path = "#{path}v#{name}".gsub(":","vv") unless name.nil?
161
+ name = "#{name}[]" if not name.nil? and element.is_array
162
+ return name, path, level
163
+ end
164
+ end
165
+ class StrTree
166
+ attr_accessor :line, :parent,:children, :name
167
+ def initialize(parent, level, root)
168
+ @parent=parent if level > -1
169
+ root << self if level == -1
170
+ @parent.add(self, level) unless @parent.nil?
171
+ end
172
+
173
+ def add(child, level=0)
174
+ @children ||= []
175
+ if level == 0
176
+ @children << child unless @children.include?(child)
177
+ else
178
+ @parent.add(child, level - 1)
179
+ end
180
+ end
181
+ def ==(other)
182
+ return false unless other.kind_of?(StrTree)
183
+ if @line == other.line and @parent == other.parent and @children == other.children
184
+ return true
185
+ end
186
+ end
187
+ def root
188
+ return parent.root unless parent.nil?
189
+ return self
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,197 @@
1
+ require 'rubygems'
2
+ gem 'soap4r'
3
+ require 'mappum/xml_transform'
4
+ require 'soap/marshal'
5
+ require 'mappum/mapserver/mapgraph'
6
+ require 'sinatra/base'
7
+ require 'erb'
8
+
9
+ module Mappum
10
+ class Mapserver < Sinatra::Default
11
+ set :views => File.join(File.dirname(__FILE__), 'views')
12
+ configure do
13
+ set :schema_dir => 'schema', :map_dir => 'map', :tmp_dir => nil
14
+ set :catalogue => nil
15
+ set :port => 9292
16
 
17
+
18
+ # FIXME make configurable
19
+ #wl = Mappum::WorkdirLoader.new(options.schema_dir, options.tmp_dir, options.map_dir)
20
+ @wl = Mappum::WorkdirLoader.new('schema', 'map')
21
+ @wl.generate_and_require
22
+ end
23
+ helpers do
24
+ def explain_func(element)
25
+ name = element.name.to_s
26
+ name ||= "self"
27
+ func = element.func.gsub(/^self/,name)
28
+ #replace [](1) with [1]
29
+ func = func.gsub(/\.\[\]\((.*)\)/,"[\\1]")
30
+ return "Simple function call: \"#{func}\"<br/>"
31
+ end
32
+ def explain(map)
33
+ str=""
34
+ if not map.right.nil? and not map.right.func.nil?
35
+ str+= explain_func(map.right)
36
+ elsif not map.from.nil? and not map.from.func.nil?
37
+ str+= explain_func(map.from)
38
+ end
39
+ unless map.func.nil?
40
+ str+= "Multiline function call (see source)<br/>"
41
+ end
42
+ unless map.dict.nil?
43
+ str+= "Dictionary mapping:<br/>"
44
+ str+= "<table border=\"1\">"
45
+ str+= "<tr><td>#{map.left.name}</td><td>#{map.right.name}</td></tr>"
46
+ map.dict.each do |k,v|
47
+ str+= "<tr><td>#{k}</td><td>#{v}</td></tr>"
48
+ end
49
+ str+= "</table>"
50
+ end
51
+ return str
52
+ end
53
+ def get_xmlns(namespace)
54
+ @namespaces ||= {}
55
+ @i ||= 0
56
+ @namespaces[namespace] = "ns#{@i+=1}" unless @namespaces.include?(namespace)
57
+ return @namespaces[namespace]
58
+ end
59
+ end
60
+ #make get methods for xsd files
61
+ Dir.glob('schema'+'/**/*.xsd') do |filename|
62
+ get "/"+filename do
63
+ [200, {"Content-Type" => "text/xml"}, IO.read(filename)]
64
+ end
1
65
  end
66
+ post "/transform" do
67
+ map_name = nil
68
+ map_name = params["map"] unless params["map"].nil? or params["map"] == "auto_select"
69
+
70
+ rt = Mappum::XmlTransform.new(options.catalogue)
71
+
72
+ xml = params["doc"]
73
+ content = rt.transform(xml,map_name)
74
+
75
+ [200, {"Content-Type" => "text/xml"}, [content]]
76
+ end
77
+ post "/transform-ws" do
78
+ map_name = env["HTTP_SOAPACTION"] unless env["HTTP_SOAPACTION"].nil? or env["HTTP_SOAPACTION"] == ""
79
+ #remove "" if present
80
+ map_name = map_name[1..-2] if map_name =~ /^".*"$/
81
+
82
+ rt = Mappum::XmlTransform.new(options.catalogue)
83
+
84
+ xml = env["rack.input"].read
85
+ begin
86
+ content = rt.transform(xml,map_name)
87
+ rescue Exception => e
88
+ @error = e
89
+ return [200, {"Content-Type" => "text/xml"}, [erb(:'ws-error')]]
90
+ end
91
+ return [200, {"Content-Type" => "text/xml"}, [content]]
92
+ end
93
+ get "/transform-ws.wsdl" do
94
+
95
+ @xml_imports = {}
96
+ Dir.glob('schema'+'/**/*.xsd') do |xsd_file|
97
+ namespace = XmlSupport.get_target_ns(xsd_file)
98
+ @xml_imports[xsd_file] = namespace unless namespace.nil?
99
+ #FIXME log warning
100
+ end
101
+
102
+ @xml_maps = []
103
+ @xml_elements = Set.new
104
+ Mappum.catalogue(options.catalogue).list_map_names.each do |mapname|
105
+ map = Mappum.catalogue(options.catalogue)[mapname]
106
+
107
+ from_qname = XSD::Mapping::Mapper.get_qname_from_class(map.from.clazz)
108
+ @xml_elements << from_qname unless from_qname.nil?
109
+ from_qname ||= XSD::QName.new(nil,"any")
110
+
111
+
112
+ to_qname = XSD::Mapping::Mapper.get_qname_from_class(map.to.clazz)
113
+ @xml_elements << to_qname unless to_qname.nil?
114
+ to_qname ||= XSD::QName.new(nil,"any")
115
+
116
+ @xml_maps << [mapname, from_qname, to_qname]
117
+ end
118
+
119
+ [200, {"Content-Type" => "text/xml"}, [erb(:'transform-ws.wsdl')]]
2
120
  end
121
+
122
+ get "/svggraph" do
123
+ map_name = params["map"]
124
+ map = Mappum.catalogue(options.catalogue).get_bidi_map(map_name)
125
+ map ||= Mappum.catalogue(options.catalogue)[map_name]
126
+ return [404, {"Content-Type" => "text/html"}, ["No map " + map_name]] if map.nil?
127
+ graph = Mappum::MapServer::Graph.new(map)
128
+ [200, {"Content-Type" => "image/svg+xml"}, graph.getSvg]
129
+
130
+ end
131
+ get "/pnggraph" do
132
+ map_name = params["map"]
133
+ map = Mappum.catalogue(options.catalogue).get_bidi_map(map_name)
134
+ map ||= Mappum.catalogue(options.catalogue)[map_name]
135
+ return [404, {"Content-Type" => "text/html"}, ["No map '#{map_name}'"]] if map.nil?
136
+ graph = Mappum::MapServer::Graph.new(map)
137
+ [200, {"Content-Type" => "image/png"}, graph.getPng]
138
+
139
+ end
140
+ get "/doc" do
141
+ map_name = params["map"]
142
+ map = Mappum.catalogue(options.catalogue).get_bidi_map(map_name)
143
+ map ||= Mappum.catalogue(options.catalogue)[map_name]
144
+ return [404, {"Content-Type" => "text/html"}, ["No map " + map_name]] if map.nil?
145
+ graph = Mappum::MapServer::Graph.new(map)
146
+ text = <<HTML
147
+ <body>
148
+ <h1>#{map_name}</h1>
149
+ <p>
150
+ #{map.desc}
151
+ </p>
152
+ <object type="image/svg+xml" data="/svggraph?map=#{map_name}"><img src="/pnggraph?map=#{map_name}"></object>
153
+ <table border="1" cellspacing="0">
154
+ <tr><td>Number</td><td>Description</td><td>Technical explanation</td></tr>
155
+ #{graph.edge_maps.keys.sort.collect{|k| "<tr><td>#{k}</td><td>#{graph.edge_maps[k].desc}&nbsp;</td><td>#{explain(graph.edge_maps[k])}&nbsp;</td></tr>"}}
156
+ </table>
157
+ </body>
158
+ HTML
159
+ [200, {"Content-Type" => "text/html"}, [text]]
160
+ end
161
+ get "/" do
162
+ content404 = <<HTML
163
+ <body>
164
+ <FORM action="transform" method="post">
165
+ <P>
166
+ <select name="map">
167
+ <option value="auto_select" selected="true">auto select</option>
168
+ #{Mappum.catalogue(options.catalogue).list_map_names.collect{|mn| "<option value='#{mn}'>#{mn}</option>"}}
169
+ </select>
170
+ <br/>
171
+ <TEXTAREA name="doc" rows="20" cols="80"></TEXTAREA><br/>
172
+ <INPUT type="submit" value="Send"/><INPUT type="reset"/>
173
+ </P>
174
+ </FORM>
175
+ <BR/>
176
+ Bidirectional maps:<p>
177
+ #{Mappum.catalogue(options.catalogue).list_bidi_map_names.collect{|mn| "<a href='/doc?map=#{mn}'>#{mn}</a><br/>"}}
178
+ </p>
179
+ <BR/>
180
+ Unidirectional maps:<p>
181
+ #{Mappum.catalogue(options.catalogue).list_map_names.collect{|mn| "<a href='/doc?map=#{mn}'>#{mn}</a><br/>"}}
182
+ </p> </body>
183
+ HTML
184
+ [200, {"Content-Type" => "text/html"}, [content404]]
185
+ end
186
+ def self.parseopt
187
+ require 'optparse'
188
+ OptionParser.new { |op|
189
+ op.on('-x') { set :lock, true }
190
+ op.on('-e env') { |val| set :environment, val.to_sym }
191
+ op.on('-s server') { |val| set :server, val }
192
+ op.on('-p port') { |val| set :port, val.to_i }
193
+ }.parse!
194
+ end
195
+ end
196
+ end
197
+ if File.basename($0) == File.basename(__FILE__)
198
+ Mappum::Mapserver.parseopt
199
+ Mappum::Mapserver.run!
200
+ end
@@ -0,0 +1,50 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <wsdl:definitions name="transfer-ws"
3
+ targetNamespace="http://mappum.ivmx.pl/transfer-ws/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
4
+ xmlns:tns="http://mappum.ivmx.pl/transfer-ws/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
6
+ <%@xml_imports.each do |file, namespace|%>
7
+ xmlns:<%=get_xmlns(namespace)%>="<%=namespace%>"
8
+ <%end%>>
9
+
10
+ <%@xml_imports.each do |file, namespace|%>
11
+ <wsdl:import namespace="<%=namespace%>"
12
+ location="<%=file%>"/>
13
+ <%end%>
14
+ <%@xml_elements.each do |qname|%>
15
+ <wsdl:message name="<%=qname.name%>">
16
+ <wsdl:part name="parameters" element="<%=get_xmlns(qname.namespace)%>:<%=qname.name%>"/>
17
+ </wsdl:message>
18
+ <%end%>
19
+ <wsdl:message name="any">
20
+ <wsdl:part name="parameters" type="xsd:anyType"/>
21
+ </wsdl:message>
22
+ <wsdl:portType name="default">
23
+ <%@xml_maps.each do |name, from, to|%>
24
+ <wsdl:operation name="<%=name%>">
25
+ <wsdl:input message="tns:<%=from.name%>"/>
26
+ <wsdl:output message="tns:<%=to.name%>"/>
27
+ </wsdl:operation>
28
+ <%end%>
29
+ </wsdl:portType>
30
+ <wsdl:binding name="binding" type="tns:default">
31
+ <soap:binding style="document"
32
+ transport="http://schemas.xmlsoap.org/soap/http" />
33
+ <%@xml_maps.each do |name, from, to|%>
34
+ <wsdl:operation name="<%=name%>">
35
+ <soap:operation soapAction="<%=name%>" />
36
+ <wsdl:input>
37
+ <soap:body use="literal" />
38
+ </wsdl:input>
39
+ <wsdl:output>
40
+ <soap:body use="literal" />
41
+ </wsdl:output>
42
+ </wsdl:operation>
43
+ <%end%>
44
+ </wsdl:binding>
45
+ <wsdl:service name="transfer">
46
+ <wsdl:port name="http" binding="tns:binding">
47
+ <soap:address location="http://localhost:9292/transform-ws" />
48
+ </wsdl:port>
49
+ </wsdl:service>
50
+ </wsdl:definitions>
@@ -0,0 +1,10 @@
1
+ <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <env:Body>
3
+ <env:Fault>
4
+ <faultcode><%=ERB::Util.html_escape @error.class.to_s%></faultcode>
5
+ <faultstring><%=ERB::Util.html_escape @error.message%></faultstring>
6
+ <faultactor>Server</faultactor>
7
+ <detail><%=ERB::Util.html_escape @error.backtrace.join("\n")%></detail>
8
+ </env:Fault>
9
+ </env:Body>
10
+ </env:Envelope>