Chris@0: /* $Id$ Chris@0: Chris@0: Part of SWI-Prolog Chris@0: Chris@0: Author: Jan Wielemaker Chris@0: E-mail: wielemak@science.uva.nl Chris@0: WWW: http://www.swi-prolog.org Chris@0: Copyright (C): 2004-2006, University of Amsterdam Chris@0: Chris@0: This program is free software; you can redistribute it and/or Chris@0: modify it under the terms of the GNU General Public License Chris@0: as published by the Free Software Foundation; either version 2 Chris@0: of the License, or (at your option) any later version. Chris@0: Chris@0: This program is distributed in the hope that it will be useful, Chris@0: but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: GNU General Public License for more details. Chris@0: Chris@0: You should have received a copy of the GNU Lesser General Public Chris@0: License along with this library; if not, write to the Free Software Chris@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Chris@0: Chris@0: As a special exception, if you link this library with other files, Chris@0: compiled with a Free Software compiler, to produce an executable, this Chris@0: library does not by itself cause the resulting executable to be covered Chris@0: by the GNU General Public License. This exception does not however Chris@0: invalidate any other reasons why the executable file might be covered by Chris@0: the GNU General Public License. Chris@0: */ Chris@0: Chris@0: :- module(serql_server, Chris@0: [ serql_server/0, Chris@0: serql_server/1, % +Options Chris@0: serql_welcome/0 Chris@0: ]). Chris@0: Chris@0: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Chris@0: This module loads the SWI-Prolog SeRQL server as a library, providing Chris@0: the public predicates defined in the header. Before loading this file, Chris@0: the user should set up a the search path `serql'. For example: Chris@0: Chris@0: :- dynamic Chris@0: user:file_search_path/2. Chris@0: :- multifile Chris@0: user:file_search_path/2. Chris@0: Chris@0: user:file_search_path(serql, '/usr/local/serql'). Chris@0: Chris@0: :- use_module(serql(load)). Chris@0: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Chris@0: Chris@0: :- dynamic Chris@0: user:file_search_path/2. Chris@0: :- multifile Chris@0: user:file_search_path/2. Chris@0: Chris@0: :- ( user:file_search_path(serql, _) Chris@0: -> true Chris@0: ; prolog_load_context(directory, Dir), Chris@0: assert(user:file_search_path(serql, Dir)) Chris@0: ). Chris@0: Chris@0: user:file_search_path(triple20, serql('Triple20/src')). Chris@0: user:file_search_path(library, serql(lib)). Chris@0: user:file_search_path(ontology_root, serql('Ontologies')). Chris@0: Chris@0: :- load_files([version], [silent(true), if(not_loaded)]). Chris@0: :- check_prolog_version(50625). % Demand >= 5.6.25 Chris@0: Chris@0: :- load_files([ parms, Chris@0: library(option), Chris@0: library(debug), Chris@0: library(lists), Chris@0: library(settings), Chris@0: library(error), Chris@0: library(broadcast), Chris@0: server, Chris@0: library('semweb/rdf_db'), Chris@0: library('semweb/rdf_persistency'), Chris@0: library('semweb/rdf_portray'), Chris@0: library('http/http_session'), Chris@0: library(http/thread_httpd), Chris@0: user_db, Chris@0: openid, Chris@0: rdf_store, Chris@0: jrn_export Chris@0: ], Chris@0: [ %silent(true), Chris@0: if(not_loaded) Chris@0: ]). Chris@0: Chris@0: %% serql_server is det. Chris@0: %% serql_server(+Options) is det. Chris@0: % Chris@0: % Start the HTTP server. Defined options are: Chris@0: % Chris@0: % * port(Port) Chris@0: % Attach to Port instead of the port specified in the Chris@0: % configuration file. Chris@0: % Chris@0: % * after_load(+Goal) Chris@0: % Run Goal after loading/initialising the database. Note Chris@0: % that serql_server/1 is not a meta-predicate. Goal is Chris@0: % called in =user= and must be prefixed if calling in Chris@0: % another module is required. Chris@0: % Chris@0: % In addition, all settings as defined in parms.pl are allowed as Chris@0: % options: Chris@0: % Chris@0: % == Chris@0: % ?- serql_server([max_idle_time(600)]). Chris@0: % == Chris@0: Chris@0: serql_server :- Chris@0: serql_server([]). Chris@0: Chris@0: serql_server(Options) :- Chris@0: load_settings('settings.db'), Chris@0: after_load_option(Options, AfterLoad, Options1), Chris@0: set_options(Options1, Options2), Chris@0: setting(http:port, Port), Chris@0: attach_account_info, Chris@0: set_session_options, Chris@0: rdf_setup_store(Options2), Chris@0: user:AfterLoad, Chris@0: setting(http:workers, Workers), Chris@0: setting(http:worker_options, Settings), Chris@0: merge_options([workers(Workers)|Options2], Settings, HTTPOptions), Chris@0: serql_server(Port, HTTPOptions), Chris@0: print_message(informational, serql(server_started(Port))). Chris@0: Chris@0: after_load_option(Options0, AfterLoad, Options) :- Chris@0: select(after_load(AfterLoad), Options0, Options), !. Chris@0: after_load_option(Options, true, Options). Chris@0: Chris@0: Chris@0: %% set_options(+List, -NotProcesses) Chris@0: % Chris@0: % Set parameters as defined in parms.pl from all options that Chris@0: % match a setting name. Using +Option(Value, ...), multiple rules Chris@0: % are appended. Chris@0: Chris@0: set_options([], []). Chris@0: set_options([+Opt|T0], T) :- !, Chris@0: Opt =.. [Name, Value], Chris@0: current_setting(serql_parms:Name), !, Chris@0: setting(serql_parms:Name, Old), Chris@0: must_be(list(any), Old), Chris@0: ( memberchk(Value, Old) Chris@0: -> true Chris@0: ; set_setting(serql_parms:Name, [Value|Old]) Chris@0: ), Chris@0: set_options(T0, T). Chris@0: set_options([Opt|T0], T) :- Chris@0: Opt =.. [Name, Value], Chris@0: current_setting(serql_parms:Name), !, Chris@0: set_setting(serql_parms:Name, Value), Chris@0: set_options(T0, T). Chris@0: set_options([H|T0], [H|T]) :- Chris@0: set_options(T0, T). Chris@0: Chris@0: Chris@0: attach_account_info :- Chris@0: setting(serql_parms:user_data, File), Chris@0: set_user_database(File). Chris@0: Chris@0: %% set_session_options Chris@0: % Chris@0: % Initialise session timeout from =|http:max_idle_time|=. Chris@0: Chris@0: set_session_options :- Chris@0: setting(http:max_idle_time, Idle), Chris@0: http_set_session_options([timeout(Idle)]). Chris@0: Chris@0: Chris@0: /******************************* Chris@0: * UPDATE SETTINGS * Chris@0: *******************************/ Chris@0: Chris@0: :- listen(settings(changed(http:max_idle_time, _, New)), Chris@0: http_set_session_options([timeout(New)])). Chris@0: :- listen(settings(changed(http:workers, _, New)), Chris@0: ( must_be(between(1, 50), New), Chris@0: setting(http:port, Port), Chris@0: http_workers(Port, New))). Chris@0: Chris@0: Chris@0: %% serql_welcome Chris@0: % Chris@0: % Print welcome banner. Chris@0: Chris@0: serql_welcome :- Chris@0: setting(http:port, Port), Chris@0: print_message(informational, serql(welcome(Port))). Chris@0: Chris@0: Chris@0: Chris@0: Chris@0: /******************************* Chris@0: * MESSAGES * Chris@0: *******************************/ Chris@0: Chris@0: :- multifile Chris@0: prolog:message/3. Chris@0: Chris@0: prolog:message(serql(server_started(Port))) --> Chris@0: [ 'Started SeRQL server at port ~w'-[Port], nl, Chris@0: 'You may access the server at http://localhost:~w/'-[Port] Chris@0: ]. Chris@0: prolog:message(serql(welcome(DefaultPort))) --> Chris@0: [ nl, Chris@0: 'Use one of the calls below to start the SeRQL server:', nl, nl, Chris@0: ' ?- serql_server. % start at port ~w'-[DefaultPort], nl, Chris@0: ' ?- serql_server([port(Port)]). % start at Port' Chris@0: ]. Chris@0: Chris@0: Chris@0: /******************************* Chris@0: * XREF * Chris@0: *******************************/ Chris@0: Chris@0: :- multifile Chris@0: prolog:called_by/2. Chris@0: Chris@0: prolog:called_by(serql_server(Options), Goals) :- Chris@0: findall(G, (member(after_load(G), Options), callable(G)), Goals).