Hi devs,
This is somewhat in response to the discussion about the new
Administration page design.
Behind the scenes, there was a discussion about where should the Import
page put the uploaded xar, in XWiki.Import (as it is done now), or in
XWiki.XWikiPreferences. Both sides agreed that the administration should
automatically find and use administration pages, but didn't agree on
what "use" means. So, how should things work?
A. The main administration page contains links to other pages
B. The main administration page includes other administration sheets
Option A means that each administration topic uses its own page to store
configuration, which somehow breaks the current configuration mechanism,
where all (global) settings go into the XWiki.XWikiPreferences page.
Option B means that each administration document is used only as a
sheet, so all objects will be in XWiki.XWikiPreferences. If we choose B,
then the best thing to do is to attach imported xars to the
XWikiPreferences page, instead of Import. Doing otherwise will either be
very hard or would break the convention.
So, the main question is: Do we keep all settings in the same document?
Or do we allow each application/component to have its configuration in
its own document?
I think it would be better to have all the configuration in one place,
instead of spreading it all over the wiki. And since we're touching the
configuration part, I think we should completely rewrite this part, as
the current system is sooo bad (I mean the
XWiki#get[User/Web/XWiki]Preference[AsSomething] methods and the giant
XWikiPreferences class). This was supposed to be a Configuration
proposal that I was thinking about, but didn't have the time to write
until now. So here it is:
Requirements:
1. We should allow an application/component to be configured at the
farm, wiki, space, user and document level (the specificity can be
configured for each setting), with static values in the component's xml
configuration and default values in the java class file or in the
template/wiki document using the configuration (depending on whether
there is a component/java/template part).
2. An application should be able to define its own customization
xclasses, the same class being usable for all levels of customization
(now, some settings go both in XWikiUsers class and XWikiPreferences
class). In fact, XWikiPreferences should disappear completely.
3. Global (farm) settings should go in
[mainwiki]:Admin/GlobalPreferences, wiki settings should go in
Admin/WikiPreferences, space settings should go in
<Space>/SpacePreferences, user settings should go in the user profile.
The current locations are inappropriate (WebPreferences??). [I'm not
sure if Preferences is a good name, as the list of blog categories is
not exactly "preferences", but more like "settings"]
4. The settings pages include an administration sheet, which later lists
all customization pages in the wiki that are customizable at that level
(for the moment, using an explicit search, later using Interface
Extensions).
5. The configuration should be accessible using a simple API, which
should find the right settings, internally taking care of all the
details: consider the lowest level for that setting (some settings are
valid only at the wiki level, or even global, so don't search or allow
settings at a lower level), security (some settings should only be taken
into consideration if the author is trusted), in-wiki and in-file
settings. This means that the application should call one method, and
not have a complicated code combining getUserPreference,
getWebPreference, getXWikiPreference and Param.
6. All this should be done without changing the data model (meaning that
we use the classic xclasses/xobjects for this).
How things work:
An application lists one or several wiki documents in its application
description as customization classes. Administration sheets (also from
the application) are then autoincluded in the global, wiki or space
Administration page, and in the user settings page. Such a sheet would
check if the class allows customization at the current level, and if
not, warns about this. If there is no instance of the target class, it
provides a link for creating one (doing it automatically is another
option, but I don't think it is a good idea, as this pollutes the wiki
with unused objects). The sheets should follow a common guideline, for
consistency. All options should be documented in the sheet.
The application code then calls the settings component API to check the
settings that apply for the current document/user. Of course, all this
with lots of caching for good performance (this is not the case in the
current core, as a lot of time is spent cloning XWikiPreferences in
HibernateCacheStore).
The hard part is deciding how to configure these classes and sheets.
Since we shouldn't use different Property types, we can't add a
customizationLevel metaproperty. A feasible solution would be to require
all properties in the same class to have the same level of
configuration, and either specify in the application description, or use
a tag for that. The best would be to have a document property, but the
current data model does not have that.
Proposed API variant 1:
/* Gets the current setting for an application, from the specified class. */
String getSetting(applicationName, className, settingName);
/* Same as above, when the application has only one settings class
defined. */
String getSetting(applicationName, settingName);
/* If the current document is known to belong to a certain application,
get a setting for that application */
String getSetting(settingName);
/* Stops at a specified level, instead of the default one. */
String getSettingForLevel(applicationName, className, settingName,
maxLevel);
/* Returns the setting at a specified level, with no inheritance. */
String getSettingAtLevel(applicationName, className, settingName,
exactLevel);
Proposed API variant 2:
/* Search for the setting name in the attached objects. */
String getSetting(settingName);
/* Gets the current setting, from the specified class. */
String getSetting(settingName, className);
/* Stops at a specified level, instead of the default one. */
String getSettingForLevel(settingName, className, maxLevel);
/* Returns the setting at a specified level, with no inheritance. */
String getSettingAtLevel(settingName, className, exactLevel);
- I don't know if we need methods returning other types, like int or
double, since we can use velocity tools for converting the returned string
- I don't know if we should have the applicationName in the parameter
list, or just the className; my take is that specifying the application
name is a bit more semantical and less technical
- maxLevel should be an enum, but we need a custom introspector for this
to work
- maxLevel assumes a fixed order of levels, which is an obvious one,
except for the User level. Where should that be in this order? Is the
user preference the most important one?
So, WDYT?
--
Sergiu Dumitriu
http://purl.org/net/sergiu/