/src/support/z_module_dummy.erl

https://code.google.com/p/zotonic/ · Erlang · 122 lines · 34 code · 26 blank · 62 comment · 0 complexity · b8b695ce389061ea1e4b9289aac4bca2 MD5 · raw file

  1. %% @author Marc Worrell <marc@worrell.nl>
  2. %% @copyright 2010 Marc Worrell
  3. %% Date: 2010-07-05
  4. %% @doc Dummy gen_server for modules without any gen_server code.
  5. %% We use this dummy gen_server so that we still can use a simple otp supervisor to oversee the
  6. %% running modules.
  7. %% Copyright 2010 Marc Worrell
  8. %%
  9. %% Licensed under the Apache License, Version 2.0 (the "License");
  10. %% you may not use this file except in compliance with the License.
  11. %% You may obtain a copy of the License at
  12. %%
  13. %% http://www.apache.org/licenses/LICENSE-2.0
  14. %%
  15. %% Unless required by applicable law or agreed to in writing, software
  16. %% distributed under the License is distributed on an "AS IS" BASIS,
  17. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. %% See the License for the specific language governing permissions and
  19. %% limitations under the License.
  20. -module(z_module_dummy).
  21. -author("Marc Worrell <marc@worrell.nl>").
  22. -behaviour(gen_server).
  23. %% gen_server exports
  24. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
  25. -export([start_link/1]).
  26. %% interface functions
  27. -export([
  28. ]).
  29. -record(state, {context}).
  30. %%====================================================================
  31. %% API
  32. %%====================================================================
  33. %% @spec start_link(Args) -> {ok,Pid} | ignore | {error,Error}
  34. %% @doc Starts the server
  35. start_link(Args) when is_list(Args) ->
  36. {ok, Pid} = gen_server:start_link(?MODULE, Args, []),
  37. gen_server:cast(Pid, {init, proplists:get_value(module, Args)}),
  38. {ok, Pid}.
  39. %%====================================================================
  40. %% gen_server callbacks
  41. %%====================================================================
  42. %% @spec init(Args) -> {ok, State} |
  43. %% {ok, State, Timeout} |
  44. %% ignore |
  45. %% {stop, Reason}
  46. %% @doc Initiates the server.
  47. init(Args) ->
  48. process_flag(trap_exit, true),
  49. {context, Context} = proplists:lookup(context, Args),
  50. {ok, #state{context=z_context:new(Context)}}.
  51. %% @spec handle_call(Request, From, State) -> {reply, Reply, State} |
  52. %% {reply, Reply, State, Timeout} |
  53. %% {noreply, State} |
  54. %% {noreply, State, Timeout} |
  55. %% {stop, Reason, Reply, State} |
  56. %% {stop, Reason, State}
  57. %% @doc Trap unknown calls
  58. handle_call(Message, _From, State) ->
  59. {stop, {unknown_call, Message}, State}.
  60. %% @spec handle_cast(Msg, State) -> {noreply, State} |
  61. %% {noreply, State, Timeout} |
  62. %% {stop, Reason, State}
  63. %% @doc Handle the next step in the module initialization.
  64. handle_cast({init, Module}, State) ->
  65. dummy_module_init(Module, State#state.context),
  66. {noreply, State};
  67. %% @doc Trap unknown casts
  68. handle_cast(Message, State) ->
  69. {stop, {unknown_cast, Message}, State}.
  70. %% @spec handle_info(Info, State) -> {noreply, State} |
  71. %% {noreply, State, Timeout} |
  72. %% {stop, Reason, State}
  73. %% @doc Handling all non call/cast messages
  74. handle_info(_Info, State) ->
  75. {noreply, State}.
  76. %% @spec terminate(Reason, State) -> void()
  77. %% @doc This function is called by a gen_server when it is about to
  78. %% terminate. It should be the opposite of Module:init/1 and do any necessary
  79. %% cleaning up. When it returns, the gen_server terminates with Reason.
  80. %% The return value is ignored.
  81. terminate(_Reason, _State) ->
  82. ok.
  83. %% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
  84. %% @doc Convert process state when code is changed
  85. code_change(_OldVsn, State, _Extra) ->
  86. {ok, State}.
  87. %%====================================================================
  88. %% support functions
  89. %%====================================================================
  90. %% @doc When a module doesn't implement a gen_server then check if it exports an init/1 function,
  91. %% if so then call that function with a fresh sudo context.
  92. dummy_module_init(Module, Context) ->
  93. case lists:member({init,1}, erlang:get_module_info(Module, exports)) of
  94. true -> Module:init(z_acl:sudo(Context));
  95. false -> nop
  96. end.