1 /* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * $Id: package.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $
23 #include <attributes.h>
26 class package : public module{
37 * Constructor for a module initializes the package attributes.
51 * Callback function for package initialization code.
57 set_attribute("package:components", ([ ]) );
58 set_attribute("package:log", ({ }) );
59 set_attribute("package:factories", ([ ]) );
60 set_attribute("package:classes", ([ ]) );
61 set_attribute("package:class_ids", 1);
69 * Initialize the module and call the init_package function.
85 * The package was loaded. Callback function.
97 * Load the module. Calls load_package.
103 if ( !mappingp(query_attribute("package:factories")) )
104 set_attribute("package:factories", ([ ]) );
105 if ( !mappingp(query_attribute("package:classes")) )
106 set_attribute("package:classes", ([ ]) );
107 if ( query_attribute("package:class_ids") == 0 )
108 set_attribute("package:class_ids", 1);
117 * This function will be called when the package is being installed.
121 void install_package(string source, string|void version)
129 * This function will be called when the package is being uninstalled.
132 void uninstall_package ()
140 * Function called when the package is uninstalled.
148 mixed comps = do_query_attribute("package:components") || ([ ]);
150 foreach ( indices(comps), string comp )
152 if ( objectp(val=comps[comp]) )
154 if ( val->get_object_class() & CLASS_OBJECT )
157 else if ( intp(val) && val == 1 )
159 // this wont happen I guess...
160 LOG("Removing file " + comp);
170 * Package uninstallation function calls uninstall().
177 LOG("pck_uninstall()");
187 void delete_object ()
189 try_event( EVENT_DELETE, CALLER );
190 mixed err = catch( uninstall() );
191 if ( err ) werror( "%s\n%O\n", err[0], err[1] );
200 * Can be called in order to update the packet. This is used by the web-package
210 * Called when the package is installed and calls install_package().
211 * This function is called by the database.
213 * @param string source - the source directory to copy files from.
217 int install(string source, string|void version)
219 LOG("Installing package !");
220 if ( CALLER != _Database )
221 THROW("Caller must be the sTeam Server !", E_ACCESS);
225 install_package(source, version);
228 MESSAGE("Error while installing package: \n"+
239 * Add something to the package log attribute.
241 * @param string str - the string to log
244 void pck_log(string str)
252 * Get the logged string array for this package.
254 * @return Array of logged string messages.
263 * Add a component to this package. This function is usually
264 * used when the package is installed.
266 * @param string desc - description of the component.
267 * @param object obj - the component to add.
268 * @param string|void fname - the file name of the component inside steam.
271 void add_component(string desc, object obj,string|void fname)
275 do_append_attribute("package:components",([desc : obj ]));
276 if ( obj->get_object_class() & CLASS_DOCLPC ) {
277 object script = get_component("/scripts/"+fname);
278 array instances = obj->get_instances();
280 if ( stringp(fname) && objectp(script) &&
281 script->get_identifier() == fname &&
282 search(instances, script) >= 0 )
284 pck_log("Upgrading script: " + fname);
285 if ( objectp(obj->get_object()) )
286 master()->upgrade(object_program(obj->get_object()));
287 add_component("/scripts/"+fname, script, fname);
290 if ( objectp(script) ) {
291 // something is horrible wrong !
292 // script exists, but not in instances
293 pck_log("Replacing script " + fname);
298 pck_log("Error while deleting old script");
300 LOG("Creating new script:" + fname);
302 script = obj->execute( ([ "name": fname, ]) );
303 object scripts = _FILEPATH->path_to_object("/scripts");
304 script->move(scripts);
305 pck_log("Created new script:" + fname + " from " +
306 master()->describe_object(obj) + " (Instances:"+
307 sizeof(obj->get_instances())+")");
310 pck_log("Failed to create script: " + fname);
312 if ( objectp(script) )
313 add_component("/scripts/"+fname, script);
321 * Get a component by its description.
323 * @param string desc - description of the component to find.
324 * @return the found component.
327 get_component(string desc)
329 return do_query_attribute("package:components")[desc];
334 * Get all registered component of this package.
336 * @return mapping of components.
338 mapping get_components()
340 return copy_value(do_query_attribute("package:components"));
345 * Register an attribute inside object obj and set its default value
348 * @param object obj - the object to register the attribute.
349 * @param int|string key - the key of the attribute.
350 * @param mixed def - the attributes default value.
354 pck_reg_attribute(object obj, int|string key, mixed def, mixed acq)
356 if ( stringp(acq) && acq == REG_ACQ_ENVIRONMENT )
357 obj->set_acquire_attribute(key, obj->get_environment);
358 else if ( objectp(acq) ) {
359 if ( obj->get_object_id() != acq->get_object_id() )
360 obj->set_acquire_attribute(key, acq);
362 obj->set_acquire_attribute(key, 0);
364 LOG("Setting value for "+ obj->get_identifier() + ",key="+key+",value="+
365 (objectp(def) ? def->get_identifier():"?"));
366 obj->set_attribute(key, def);
373 * Provide an attribute for a class or one object, CLASS_ANY also includes
376 * @param object_class - an object or a class of objects, CLASS any for all
377 * @param key - the attribute key
378 * @param desc - the description of this attribute
379 * @param cntrl - the control registration info,CONTROL_ATTR_USER|SERVER|CLIENT
380 * @param perm - permission for the attribute: ATTR_FREE_READ|WRITE|RESTRICTED
381 * @param def - the default value of an attribute,
382 * only set if attribute is not acquired
383 * @param acq - acquiring information, nothing, an object or and integer for
384 * setting acquiring to the objects environment
385 * @param obj_def - the default object from that is acquired - this object
386 * will contain the default value for the attribute (see def)
387 * @see kernel/factory.register_attributes
391 provide_attribute(int|object object_class, int|string key,int type,string desc,
392 int read_event, int write_event, string|object|void acq,
393 int cntrl, mixed def, void|object obj_def)
397 if ( intp(object_class) )
399 factory = _Server->get_factory(object_class);
400 Attribute pattr = factory->describe_attribute(key);
401 Attribute attr = Attribute(key, desc, type, def, acq, cntrl,
402 read_event, write_event);
404 if ( !objectp(pattr) || pattr != attr )
406 factory->register_attribute(attr);
410 pck_reg_attribute(object_class, key, def, acq);
412 if ( objectp(obj_def) )
413 pck_reg_attribute(obj_def, key, def, acq);
420 * Add a new class handled by this package.
422 * @param int id - the class id
423 * @param object factory - the factory handling the class
424 * @param void|bool force - overwrite existing classes
426 void add_class(int id, object factory, void|bool force)
428 mapping mFactories = query_attribute("package:factories");
430 if ( !force && objectp(mFactories[id]) )
431 THROW("Class is already defined !", E_ERROR);
433 mFactories[id] = factory;
434 set_attribute("package:factories", mFactories);
439 * Register a new class and get the id for it.
441 * @param string name - the name of the class
442 * @return the class id for the class
444 int register_class(string name)
446 mapping mClasses = query_attribute("package:classes");
447 int id = query_attribute("package:class_ids");
449 set_attribute("package:classes", mClasses);
450 set_attribute("package:class_ids", (id<<1));
455 * Get the class id for a given class.
457 * @param string name - the name of the class.
458 * @return the class id or 0 if not registered.
460 int get_class_id(string name)
462 mapping mClasses = query_attribute("package:classes");
463 return mClasses[name];
468 * Get the mapping of classes handled by this package.
470 * @return mapping of classes, index is class id and value is the factory.
472 mapping get_classes()
474 return query_attribute("package:factories");
478 mixed get_config ( string key )
480 object config = get_config_object();
481 if ( !objectp(config) ) return UNDEFINED;
482 return config->get_config( key );
486 mapping get_configs ( array|void configs )
488 object config = get_config_object();
489 if ( !objectp(config) ) return UNDEFINED;
490 return config->get_configs( configs );
494 mixed set_config ( string key, mixed value )
496 object config = get_config_object( 1 );
497 if ( !objectp(config) ) return UNDEFINED;
498 return config->set_config( key, value );
502 mapping set_configs ( mapping configs )
504 object config = get_config_object( 1 );
505 if ( !objectp(config) ) return UNDEFINED;
506 return config->set_configs( configs );
510 object get_config_object ( int|void create_if_missing )
512 object config = OBJ( "/config/packages/" + get_identifier() );
513 if ( objectp(config) || !create_if_missing ) return config;
514 object package_configs = OBJ( "/config/packages" );
515 if ( !objectp(package_configs) ) return UNDEFINED;
516 config = get_factory( CLASS_DOCUMENT )->execute( ([
517 "name" : get_identifier(),
518 "mimetype" : "application/x-steam-config",
520 if ( !objectp(config) ) return UNDEFINED;
521 if ( !config->move( package_configs ) ) {
525 get_module( "decorator" )->add_decoration( config, "server:/decorations/Config.pike" );
526 config->set_attribute( OBJ_TYPE, "object_config_package" );
531 int get_object_class() { return ::get_object_class() | CLASS_PACKAGE | CLASS_SCRIPT; }
532 string get_version() { return do_query_attribute(PACKAGE_VERSION); }