1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1999-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21 22-module(ic_struct_java). 23 24-include("icforms.hrl"). 25-include("ic.hrl"). 26-include("ic_debug.hrl"). 27%%----------------------------------------------------------------- 28%% External exports 29%%----------------------------------------------------------------- 30-export([gen/3]). 31 32%%----------------------------------------------------------------- 33%% Internal exports 34%%----------------------------------------------------------------- 35-export([]). 36 37%%----------------------------------------------------------------- 38%% External functions 39%%----------------------------------------------------------------- 40gen(G, N, X) when is_record(X, struct) -> 41 StructName = ic_forms:get_java_id(X), 42 WireStructName = ic_forms:get_id2(X), 43 emit_struct_class(G, N, X, StructName), 44 emit_holder_class(G, N, X, StructName), 45 emit_helper_class(G, N, X, StructName, WireStructName), 46 N2 = [StructName ++ "Package" |N], 47 ic_jbe:gen(G, N2, ic_forms:get_body(X)); 48gen(_G, _N, _X) -> 49 ok. 50 51%%----------------------------------------------------------------- 52%% Internal functions 53%%----------------------------------------------------------------- 54 55%%----------------------------------------------------------------- 56%% Func: emit_struct_class/4 57%%----------------------------------------------------------------- 58emit_struct_class(G, N, X, StructName) -> 59 {Fd, _}= ic_file:open_java_file(G, N, StructName), 60 61 MList = struct_member_list(G, N, X), 62 ArgList = gen_parameter_list(G, [ StructName ++ "Package" |N], X, MList), 63 64 ic_codegen:emit(Fd, ["final public class ",StructName," {\n" 65 " // instance variables\n"]), 66 67 emit_struct_members_declarations(G, [StructName ++ "Package" |N], 68 X, Fd, MList), 69 70 ic_codegen:emit(Fd, ["\n // constructors\n" 71 " public ",StructName,"() {}\n\n" 72 73 " public ",StructName,"(",ArgList,") {\n"]), 74 75 emit_struct_members_initialisation(G, N, X, Fd, MList), 76 77 ic_codegen:emit(Fd, [" }\n\n" 78 79 "}\n\n"]), 80 file:close(Fd). 81 82 83%%----------------------------------------------------------------- 84%% Func: emit_holder_class/4 85%%----------------------------------------------------------------- 86emit_holder_class(G, N, _X, StructName) -> 87 SName = string:concat(StructName, "Holder"), 88 {Fd, _}= ic_file:open_java_file(G, N, SName), 89 90 ic_codegen:emit(Fd, ["final public class ",StructName,"Holder {\n" 91 92 " // instance variables\n" 93 " public ",StructName," value;\n\n" 94 95 " // constructors\n" 96 " public ",StructName,"Holder() {}\n\n" 97 98 " public ",StructName,"Holder(",StructName," initial) {\n" 99 " value = initial;\n" 100 " }\n\n" 101 102 " // methods\n"]), 103 104 ic_codegen:emit(Fd, [" public void _marshal(",?ERLANGPACKAGE,"OtpOutputStream out) throws java.lang.Exception {\n" 105 " ",StructName,"Helper.marshal(out, value);\n" 106 " }\n\n" 107 108 " public void _unmarshal(",?ERLANGPACKAGE,"OtpInputStream in) throws java.lang.Exception {\n" 109 " value = ",StructName,"Helper.unmarshal(in);\n" 110 " }\n" 111 112 "}\n\n"]), 113 file:close(Fd). 114 115%%----------------------------------------------------------------- 116%% Func: emit_helper_class/5 117%%----------------------------------------------------------------- 118emit_helper_class(G, N, X, StructName, WireStructName) -> 119 SName = string:concat(StructName, "Helper"), 120 {Fd, _}= ic_file:open_java_file(G, N, SName), 121 122 ic_codegen:emit(Fd, ["public class ",StructName,"Helper {\n" 123 124 " // constructors\n" 125 " private ",StructName,"Helper() {}\n\n" 126 127 " // methods\n"]), 128 129 MList = struct_member_list(G, N, X), 130 131 ic_codegen:emit(Fd, [" public static void marshal(",?ERLANGPACKAGE,"OtpOutputStream _out, ",StructName," _value)\n" 132 " throws java.lang.Exception {\n\n"]), 133 134 emit_struct_marshal_function(G, N, X, Fd, StructName, WireStructName, MList), 135 136 ic_codegen:emit(Fd, [" }\n\n" 137 138 " public static ",StructName," unmarshal(",?ERLANGPACKAGE,"OtpInputStream _in)\n" 139 " throws java.lang.Exception {\n\n"]), 140 141 emit_struct_unmarshal_function(G, N, X, Fd, StructName, WireStructName, MList), 142 143 ic_codegen:emit(Fd, [" }\n\n" 144 145 " public static String id() {\n" 146 " return \"",ictk:get_IR_ID(G, N, X),"\";\n" 147 " }\n\n" 148 149 " public static String name() {\n" 150 " return \"",StructName,"\";\n" 151 " }\n\n"]), 152 153 ic_jbe:emit_type_function(G, N, X, Fd), 154 155 ic_codegen:emit(Fd, [" public static void insert(",?ICPACKAGE,"Any _any, ",StructName," _this)\n" 156 " throws java.lang.Exception {\n\n" 157 158 " ",?ERLANGPACKAGE,"OtpOutputStream _os = \n" 159 " new ",?ERLANGPACKAGE,"OtpOutputStream();\n\n" 160 161 " _any.type(type());\n" 162 " marshal(_os, _this);\n" 163 " _any.insert_Streamable(_os);\n" 164 " }\n\n" 165 166 " public static ",StructName," extract(",?ICPACKAGE,"Any _any)\n" 167 " throws java.lang.Exception {\n\n" 168 169 " return unmarshal(_any.extract_Streamable());\n" 170 " }\n\n" 171 172 173 %% In corba mapping there is also a _type function here. 174 "}\n"]), 175 file:close(Fd). 176 177 178%%----------------------------------------------------------------- 179%% Func: emit_struct_members_declarations/ 180%%----------------------------------------------------------------- 181emit_struct_members_declarations(_, _, _, _, []) -> 182 ok; 183emit_struct_members_declarations(G, N, X, Fd, [{Member, _Type, Id} | MList]) -> 184 ic_codegen:emit(Fd, [" public ",ic_java_type:getType(G, N, Member)," ",Id,";\n"]), 185 emit_struct_members_declarations(G, N, X, Fd, MList). 186 187 188 189%%----------------------------------------------------------------- 190%% Func: emit_struct_members_initialisation/5 191%%----------------------------------------------------------------- 192emit_struct_members_initialisation(_, _, _, _, []) -> 193 ok; 194emit_struct_members_initialisation(G, N, X, Fd, [{_Member, _Type, Id} | MList]) -> 195 ic_codegen:emit(Fd, [" ",Id," = _",Id,";\n"]), 196 emit_struct_members_initialisation(G, N, X, Fd, MList). 197 198 199 200 201%%----------------------------------------------------------------- 202%% Func: emit_struct_marshal_function/7 203%%----------------------------------------------------------------- 204emit_struct_marshal_function(G, N, X, Fd, StructName, WireStructName, MList) -> 205 206 ic_codegen:emit(Fd, [" _out.write_tuple_head(",integer_to_list(length(MList) + 1),");\n" 207 " _out.write_atom(\"",ic_util:to_undersc([WireStructName|N]),"\");\n\n"]), 208 209 emit_struct_marshal_function_loop(G, [StructName ++ "Package" |N], 210 X, Fd, MList, 1). 211 212%%----------------------------------------------------------------- 213%% Func: emit_struct_marshal_function_loop/6 214%%----------------------------------------------------------------- 215emit_struct_marshal_function_loop(_, _, _, Fd, [], _) -> 216 ic_codegen:nl(Fd); 217emit_struct_marshal_function_loop(G, N, X, Fd, [{Member, Type, Id} |MList], Num) -> 218 219 case ic_java_type:isBasicType(G, N, Member) of 220 true -> 221 ic_codegen:emit(Fd, [" _out",ic_java_type:marshalFun(G, N, Member, Type),"(_value.",Id,");\n"]); 222 _ -> 223 if (element(1,hd(element(3,Member))) == array) -> 224 ic_codegen:emit(Fd, 225 [" ", 226 ic_util:to_dot(G,[ic_forms:get_id2(Member)|N]), 227 "Helper.marshal(_out, _value.",Id,");\n"]); 228 true -> 229 ic_codegen:emit(Fd, [" ", 230 ic_java_type:marshalFun(G, N, Member, Type), 231 "(_out, _value.",Id,");\n"]) 232 end 233 end, 234 235 emit_struct_marshal_function_loop(G, N, X, Fd, MList, Num+1). 236 237 238 239 240%%----------------------------------------------------------------- 241%% Func: emit_struct_unmarshal_function/7 242%%----------------------------------------------------------------- 243emit_struct_unmarshal_function(G, N, X, Fd, StructName, WireStructName, MList) -> 244 245 ic_codegen:emit(Fd, [" _in.read_tuple_head();\n\n" 246 247 " if ((_in.read_atom()).compareTo(\"", 248 ic_util:to_undersc([WireStructName|N]), 249 "\") != 0)\n" 250 " throw new java.lang.Exception(\"\");\n\n" 251 252 " ",StructName," _value = new ",StructName,"();\n"]), 253 254 emit_struct_unmarshal_function_loop(G, [StructName ++ "Package"|N], 255 X, Fd, MList, 1), 256 257 ic_codegen:emit(Fd, " return _value;\n"). 258 259%%----------------------------------------------------------------- 260%% Func: emit_union_unmarshal_function_loop/6 261%%----------------------------------------------------------------- 262emit_struct_unmarshal_function_loop(_, _, _, Fd, [], _) -> 263 ic_codegen:nl(Fd); 264emit_struct_unmarshal_function_loop(G, N, X, Fd, [{Member, Type, Id} |MList], Num) -> 265 266 case ic_java_type:isBasicType(G, N, Member) of 267 true -> 268 ic_codegen:emit(Fd, [" _value.",Id," = _in",ic_java_type:unMarshalFun(G, N, Member, Type),";\n"]); 269 _ -> 270 if (element(1,hd(element(3,Member))) == array) -> 271 ic_codegen:emit(Fd, 272 [" _value.",Id," = ",ic_util:to_dot(G,[ic_forms:get_id2(Member)|N]),"Helper.unmarshal(_in);\n"]); 273 true -> 274 ic_codegen:emit(Fd, 275 [" _value.",Id," = ",ic_java_type:getUnmarshalType(G, N, Member, Type),".unmarshal(_in);\n"]) 276 end 277 end, 278 279 emit_struct_unmarshal_function_loop(G, N, X, Fd, MList, Num +1). 280 281 282 283%%----------------------------------------------------------------- 284%% Func: gen_parameter_list/4 285%%----------------------------------------------------------------- 286gen_parameter_list(G, N, _X, [{Member, _Type, Id}]) -> 287 ic_java_type:getType(G,N,Member) ++ 288 " _" ++ 289 ic_util:to_list(Id); 290gen_parameter_list(G, N, X, [{Member, _Type, Id} | MList]) -> 291 ic_java_type:getType(G,N,Member) ++ 292 " _" ++ 293 ic_util:to_list(Id) ++ 294 ", " ++ 295 gen_parameter_list(G, N, X, MList). 296 297 298%%----------------------------------------------------------------- 299%% Func: struct_member_list/3 300%%----------------------------------------------------------------- 301struct_member_list(_G, _N, X) -> 302 M = lists:map( 303 fun(Member) -> 304 lists:map( 305 fun(Id) -> 306 Type = ic_forms:get_type(Member), 307 { Member, Type, ic_forms:get_java_id(Id)} 308 end, 309 ic_forms:get_idlist(Member)) 310 end, 311 ic_forms:get_body(X)), 312 lists:flatten(M). 313 314 315 316