/ucengine/src/helpers/json_helpers.erl

http://github.com/AF83/ucengine · Erlang · 200 lines · 157 code · 23 blank · 20 comment · 1 complexity · 511752514ac4d842121cd675f319bb2a MD5 · raw file

  1. %%
  2. %% U.C.Engine - Unified Collaboration Engine
  3. %% Copyright (C) 2011 af83
  4. %%
  5. %% This program is free software: you can redistribute it and/or modify
  6. %% it under the terms of the GNU Affero General Public License as published by
  7. %% the Free Software Foundation, either version 3 of the License, or
  8. %% (at your option) any later version.
  9. %%
  10. %% This program is distributed in the hope that it will be useful,
  11. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. %% GNU Affero General Public License for more details.
  14. %%
  15. %% You should have received a copy of the GNU Affero General Public License
  16. %% along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. %%
  18. -module(json_helpers).
  19. -compile({no_auto_import,[error/2]}).
  20. -include("uce.hrl").
  21. -export([format_response/4,
  22. unexpected_error/1,
  23. error/2,
  24. error/3,
  25. ok/1,
  26. true/1,
  27. false/1,
  28. created/1,
  29. created/2,
  30. json/2,
  31. json/3,
  32. to_json/2,
  33. to_struct/1]).
  34. format_response(Status, Headers, Content) ->
  35. format_response(Status, "application/json", Headers, to_struct(Content)).
  36. format_response(Status, ContentType, Headers, Content) ->
  37. Body = mochijson:encode(Content),
  38. [{status, Status},
  39. {content, ContentType, lists:flatten(Body)}] ++ Headers.
  40. add_cors_headers(Domain) ->
  41. cors_helpers:format_cors_headers(Domain).
  42. unexpected_error(Domain) ->
  43. format_response(500, add_cors_headers(Domain), [{error, unexpected_error}]).
  44. error(Domain, Reason) ->
  45. Code = http_helpers:error_to_code(Reason),
  46. format_response(Code, add_cors_headers(Domain), [{error, Reason}]).
  47. error(Domain, Reason, Infos) ->
  48. Code = http_helpers:error_to_code(Reason),
  49. format_response(Code, add_cors_headers(Domain), [{error, Reason}, {infos, Infos}]).
  50. ok(Domain) ->
  51. format_response(200, add_cors_headers(Domain), [{result, ok}]).
  52. true(Domain) ->
  53. format_response(200, add_cors_headers(Domain), [{result, "true"}]).
  54. false(Domain) ->
  55. format_response(200, add_cors_headers(Domain), [{result, "false"}]).
  56. created(Domain) ->
  57. format_response(201, add_cors_headers(Domain), [{result, created}]).
  58. created(Domain, Id) ->
  59. format_response(201, add_cors_headers(Domain), [{result, Id}]).
  60. json(Domain, Content) ->
  61. json(Domain, 200, Content).
  62. json(Domain, Status, Content) ->
  63. format_response(Status, add_cors_headers(Domain), [{result, to_json(Domain, Content)}]).
  64. %%
  65. %% Transform usual records to JSON
  66. %%
  67. to_json(Domain, Records) when is_list(Records) ->
  68. {array, [to_json(Domain, Record) || Record <- Records]};
  69. to_json(_Domain, #uce_access{action=Action,
  70. object=Object,
  71. conditions=Conditions}) ->
  72. {struct,
  73. [{action, Action},
  74. {object, Object},
  75. {conditions, Conditions}]};
  76. to_json(Domain, #uce_meeting{id=Name,
  77. metadata=Metadata}) ->
  78. {struct, [{name, Name},
  79. {domain, Domain},
  80. {metadata, Metadata}]};
  81. to_json(Domain, #uce_event{id=Id,
  82. datetime=Datetime,
  83. location=Location,
  84. from=From,
  85. type=Type,
  86. to=To,
  87. parent=Parent,
  88. metadata=Metadata}) ->
  89. JSONTo = case To of
  90. "" ->
  91. [];
  92. ToId ->
  93. [{to, ToId}]
  94. end,
  95. JSONLocation = case Location of
  96. "" ->
  97. [];
  98. Meeting ->
  99. [{location, Meeting}]
  100. end,
  101. JSONParent = case Parent of
  102. "" ->
  103. [];
  104. _ ->
  105. [{parent, Parent}]
  106. end,
  107. Metadata2 = case Metadata of
  108. {struct, _} ->
  109. Metadata;
  110. _ ->
  111. {struct, Metadata}
  112. end,
  113. {struct,
  114. [{type, Type},
  115. {domain, Domain},
  116. {datetime, Datetime},
  117. {id, Id}] ++
  118. JSONLocation ++
  119. JSONTo ++
  120. [{from, From}] ++
  121. JSONParent ++
  122. [{metadata, Metadata2}]};
  123. to_json(Domain, #uce_file{id=Id,
  124. name=Name,
  125. location=Location,
  126. uri=Uri,
  127. metadata=Metadata}) ->
  128. JSONLocation = [{location, Location}],
  129. {struct, [{id, Id},
  130. {domain, Domain},
  131. {name, Name},
  132. {uri, Uri}] ++ JSONLocation ++
  133. [{metadata, Metadata}]};
  134. to_json(Domain, #uce_presence{id=Id,
  135. user=User,
  136. auth=Auth}) ->
  137. {struct,
  138. [{id, Id},
  139. {domain, Domain},
  140. {user, User},
  141. {auth, Auth}]};
  142. to_json(Domain, #uce_user{id=Id,
  143. name=Name,
  144. auth=Auth,
  145. metadata=Metadata}) ->
  146. {struct, [{uid, Id},
  147. {name, Name},
  148. {domain, Domain},
  149. {auth, Auth},
  150. {metadata, to_struct(Metadata)}]};
  151. to_json(_Domain, Json) ->
  152. Json.
  153. -spec to_struct([{string() | atom(), any()}]) -> {struct, [{string() | atom(), any()}]}.
  154. to_struct({struct, _} = Struct) ->
  155. Struct;
  156. to_struct(Proplist) ->
  157. {struct, Proplist}.
  158. -ifdef(TEST).
  159. -include_lib("eunit/include/eunit.hrl").
  160. unexpected_error_test() ->
  161. ?assertMatch([{status, 500}, {content, "application/json", "{\"error\":\"unexpected_error\"}"},
  162. {header, "Access-Control-Allow-Origin: *"},
  163. {header, "Access-Control-Allow-Methods: GET, POST, PUT, DELETE"},
  164. {header, "Access-Control-Allow-Headers: X-Requested-With"}], unexpected_error("")).
  165. error_test() ->
  166. ?assertMatch([{status, 400}, {content, "application/json", "{\"error\":\"bad_parameters\"}"},
  167. {header, "Access-Control-Allow-Origin: *"},
  168. {header, "Access-Control-Allow-Methods: GET, POST, PUT, DELETE"},
  169. {header, "Access-Control-Allow-Headers: X-Requested-With"}], error("", bad_parameters)),
  170. ?assertMatch([{status, 500}, {content, "application/json", "{\"error\":\"hello_world\"}"},
  171. {header, "Access-Control-Allow-Origin: *"},
  172. {header, "Access-Control-Allow-Methods: GET, POST, PUT, DELETE"},
  173. {header, "Access-Control-Allow-Headers: X-Requested-With"}], error("", "hello_world")).
  174. format_response_test() ->
  175. ?assertMatch([{status, 200}, {content, "application/json", "{}"}], format_response(200, [], [])),
  176. ?assertMatch([{status, 200}, {content, "application/json", "{}"}, {header, "X-Plop: plop"}, {header, "Host: ucengine.org"}], format_response(200, [{header, "X-Plop: plop"}, {header, "Host: ucengine.org"}], [])).
  177. -endif.