first cut of merge of STABLE-pre1_0 into HEAD. I won't even guarantee that it
[mir.git] / doc / CODESTRUCTURE
1 -------------------------------------------------------------------------------
2
3 A short intro to the code-structure of Mir
4
5 -------------------------------------------------------------------------------
6
7 In the java-source tree you will find the following:
8
9  - two classes (OpenMir and Mir)
10  - two packages (mir and mircoders)
11
12
13 Servlets:
14 -------------------------------------------------------------------------------
15
16 Looking from the request of a client browser onto MIR, the http-request is
17 passed via Apache/Tomcat to either Mir.class or OpenMir.class. Mir.class
18 handles all request that deal with internal administration tasks of MIR.
19 OpenMir is the Servlet that deals with all open tasks: adding comments or
20 articles/media to the system.
21
22 These servlets don't do much but dispatching the tasks to an underlying
23 code level, called ServletModules. OpenMir.class is basically a special
24 case of Mir.class, no authentication is needed, and only two underlying
25 ServletModule are used.
26
27 The following explanation is about how requests are passed through, and
28 responses to the client-browser are generated. The request has to pass
29 through up to four levels of code (and from there asking the database),
30 until it collected all the necessary data or performed all necessary
31 tasks, to be able to respond.
32
33
34 ServletModules:
35 -------------------------------------------------------------------------------
36
37 The ServletModules are called via reflection java-api. The http-request
38 parameter "module=XXX" and "do=YYY" are evaluated. A method
39 YYY(HttpRequest,HttpResponse) is called in ServletModuleXXX.
40
41 A common mistake for those new to Java is to look for usage of a class in 
42 the code by doing a "grep -r ClassName" or something like that. In this 
43 case, grep -r ServletModuleImages for example will turn up nothing except 
44 for ServletModuleImages itself.. that is because of reflection as 
45 explained above.
46
47 The media handlers in mir.media.* work the same way as well. 
48
49  Database/Entity:
50 -------------------------------------------------------------------------------
51 - db: singeltons, object-representation of db-table, *low-level* access, 
52 generating entities, does all the dirty JDBC work. There is a Database 
53 Class for every table in the DB.
54
55 If an Entity wants to store itself in the media table, it has to have a 
56 storage object of type DatabaseMedia....
57
58 When you ask a storage object to get something, it hands back an Entity.
59 [through Database*.selectByWhereClause(), selectById().]
60
61 - entity: representation of row. Contains the contents of "select * from
62 dbname where id=rowid" in a HashMap. accessible via
63 Entity.getValue("keyname"). One can do Entity.setValue(...,
64 Entity.update() which syncs the Hash with the DB row and Entity.insert()  
65 to insert the HashMap as a new row, etc... basically high level DB access.
66 The text component of an article is an entity (EntityContent, a row from
67 the content table.) In short this is how we fetch content (whatever that
68 may be: actual data, media meta-data, media_types, etc..) from the DB and
69 write to the DB. Everything has to be reprented as an Entity.
70
71 All Entities must have a StorageObject (theStorage) which is a Database
72 object of the appropriate type. it is the connection between the entity
73 data and the DB table itself. The only way to get an Entity other than
74 asking a storage object to fetch one is to construct one by passing the
75 storage object to the Entity Konstruktor.
76
77 There is also EntityList, a list of entities..
78
79 Modules:
80 -------------------------------------------------------------------------------
81
82 - This one is a little grey... It's pretty much a wrapper around Database 
83 and Entity combined, so it's a half level higher up or so. It's not always 
84 necessary to use/have a Module either.. A usage example: you can do
85 ModuleName.getByWhereClause() and it returns a list of Entities that match 
86 the query. Like entities you must have a StorageObject to access the DB. 
87 but unlike Entity, you can start out without one. Modules use Entity and 
88 Database objects internally. [Actually it uses Database object internally 
89 and returns Entitys...]
90
91 Also I believe the intention was/is that it should be used in place of 
92 Entity for any *logic* that would normally have to into an Entity as 
93 Entity should be free of a case specific logic in theory. But that's not
94 always true if you use EntityImages as an example, but that seems to be 
95 because EntityImages needs low-level DB connections.
96
97 Producer
98 -------------------------------------------------------------------------------
99
100 Well, what makes Mir different than other Content Management Systems is
101 that it does not generate the content pages dynamically or use simple
102 caching methods. Rather it generates static .[s]html files exclusively.  
103 This makes mir very fast under high viewing loads as it does not use
104 servlets for this at all. It also makes it very easy to mirror as the
105 mirrors do not have to run any Mir code, they only have to have a static
106 webserver. In fact the first site to use Mir, germany.indymedia.org is on
107 a whole other machine on another continent than the machine that
108 *produces* the static files. Germany.indymedia.org already has 3 mirrors.
109
110 The mircoders.producer.* classes are responsible for creating these static 
111 .html files and the filesystem structure that they reside in. This 
112 includes files that are article summaries and files that are the whole 
113 article themselves. Some media types also require Producers.
114
115 If the main content *viewing* server is on another host, the FS tree is
116 then rsync'ed to the viewing host.
117
118 The Producers are called exclusively from the ServletModules in
119 mircoders.servlet.*. They are called when a new article/comment is added,
120 or when an administrator/moderator makes modifications to the site or when
121 a manual update is desired. The method "handle()" is the one that does all
122 work it takes parameters that tell it to force update all files even if
123 their contents is unchanged, etc.. some Producers take an article ID as an
124 argument telling them to create the html page representing the article and
125 any summary pages that might be changed due to the addition of the
126 article.
127
128 Producers of course use Entities, Database, MediaHandler and Module
129 objects internally.
130
131 A dB field called is_produced is used to determine wether or not an Object 
132 needs to be produced.
133
134 Oh and before I forget, it generates the pages based on a template. It 
135 uses the Freemarker templating system. Doc on freemarker is available at 
136 freemarker.sourceforge.net I believe. 
137
138 TODO: In theory it would be cool if we could abstract the output mechanism
139 further to use other types of templates and to generate content other than
140 HTML (like WAP for example). 
141
142 Media Handlers
143 -------------------------------------------------------------------------------
144 They are kind of helper classes to deal with different representations of
145 media types. They are called via the java reflection API. The class names 
146 are resolved through the media_type table. See 
147 source/mir/media/MirMedia.java for documentation.
148
149 Helper classes
150 -------------------------------------------------------------------------------
151 mir.misc.* (source/mir/misc/*) contains a bunch of classes that do Regexp, 
152 file handling and those sorts of things. Always look here first before 
153 writing such a thing.