Source code: com/dghda/kent/ReportEngine.java
1 /* Copyright (C) 2001 Duane Griffin <duanegriffin@users.sourceforge.net>
2 This file is part of Kent.
3
4 Kent is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 Kent is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public
15 License along with Kent; see the file COPYING. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 */
19
20 package com.dghda.kent;
21
22 import java.io.*;
23 import java.util.*;
24
25 import com.dghda.log.*;
26 import com.dghda.module.*;
27
28 /**
29 The report engine manages the available reports, actions and transforms.
30 */
31 public class ReportEngine {
32
33 /** The DTD that defines configuration options. */
34 public static final String CONFIG_DTD = "kentconfig.dtd";
35
36 /** The preamble of a config spec. */
37 public static final String CONFIG_SPEC_START =
38 ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
39 "<!DOCTYPE KentConfig SYSTEM \"" + CONFIG_DTD +
40 "\">\n\n<KentConfig>\n");
41
42 /** The end of a config spec. */
43 public static final String CONFIG_SPEC_END = "</KentConfig>\n";
44
45 /** An empty config spec. */
46 public static final String EMPTY_CONFIG = (CONFIG_SPEC_START + CONFIG_SPEC_END);
47
48 /** A radio-button type select. */
49 public static final int SELECT_STYLE_RADIO = 0;
50
51 /** A check-box type select. */
52 public static final int SELECT_STYLE_CHECK = 1;
53
54 /** A combo-box type select. */
55 public static final int SELECT_STYLE_COMBO = 2;
56
57 /**
58 Create a new report engine, using the given report & DTD path(s).
59 @param auth The authorisation manager which controls access to reports.
60 @param env The environment the engine runs in.
61 @throws EngineInitialisationException If a component of a given path is invalid.
62 */
63 public ReportEngine (AuthorisationManager auth, ReportEnvironment env) throws EngineInitialisationException {
64 m_Authorisation = auth;
65 m_Environment = env;
66
67 String reportPaths = m_Environment.getReportPath();
68 String actionPaths = m_Environment.getActionPath();
69 String transformPaths = m_Environment.getTransformPath();
70 m_Environment.log ("Loading reports from " + reportPaths);
71 m_Environment.log ("Loading actions from " + actionPaths);
72 m_Environment.log ("Loading transforms from " + transformPaths);
73
74 // Initialise the arguments to pass to module provider's constructors
75 Object [] providerArgs = new Object[1];
76 providerArgs[0] = this;
77
78 // Create loaders
79 try {
80 m_ReportLoader = new ModuleLoader (Report.class, reportPaths, providerArgs, m_Environment);
81 m_ActionLoader = new ModuleLoader (ReportAction.class, actionPaths, providerArgs, m_Environment);
82 m_TransformLoader = new ModuleLoader (ReportTransform.class, transformPaths, providerArgs, m_Environment);
83 } catch (InvalidPathException exc) {
84 throw new EngineInitialisationException ("Unable to initialise module loaders (invalid path)", exc);
85 }
86 }
87
88 /**
89 Returns a list of all reports available to the given user.
90 @param user The authenticated user, or null if not authenticated
91 */
92 public synchronized List getAvailableReports (String user) {
93 return getAvailableModules (m_ReportLoader, user);
94 }
95
96 /**
97 Returns a list of all actions available to the given user.
98 @param user The authenticated user, or null if not authenticated
99 */
100 public synchronized List getAvailableActions (String user) {
101 return getAvailableModules (m_ActionLoader, user);
102 }
103
104 /**
105 Returns a list of all transforms available to the given user.
106 @param user The authenticated user, or null if not authenticated
107 */
108 public synchronized List getAvailableTransforms (String user) {
109 return getAvailableModules (m_TransformLoader, user);
110 }
111
112 /**
113 Returns the given report.
114 @param id The report's ID.
115 @param user The user who wants to access the report.
116 @returns null if no such report exists, or if not authorised.
117 */
118 public synchronized Report getReport (String id, String user) {
119 Report result = (Report) m_ReportLoader.getModule (id);
120 if (result != null && !canAccessModule (result, user)) {
121 result = null;
122 m_Environment.log ("Attempt to access unauthorised report " + id + " by " + user);
123 }
124 return result;
125 }
126
127 /**
128 Returns the given action.
129 @param id The action's ID.
130 @param user The user who wants to access the action.
131 @returns null if no such action exists, or if not authorised.
132 */
133 public synchronized ReportAction getAction (String id, String user) {
134 ReportAction result = (ReportAction) m_ActionLoader.getModule (id);
135 if (result != null && !canAccessModule (result, user)) {
136 result = null;
137 m_Environment.log ("Attempt to access unauthorised action " + id + " by " + user);
138 }
139 return result;
140 }
141
142 /**
143 Returns the given transform.
144 @param id The transform's ID.
145 @param user The user who wants to access the transform.
146 @returns null if no such transform exists, or if not authorised.
147 */
148 public synchronized ReportTransform getTransform (String id, String user) {
149 ReportTransform result = (ReportTransform) m_TransformLoader.getModule (id);
150 if (result != null && !canAccessModule (result, user)) {
151 result = null;
152 m_Environment.log ("Attempt to access unauthorised transform " + id + " by " + user);
153 }
154 return result;
155 }
156
157 /**
158 Adds the given report.
159 @param report The report to add.
160 @returns True if the report was added.
161 */
162 public synchronized boolean addReport (Report report) {
163 return m_ReportLoader.addModule (report);
164 }
165
166 /**
167 Adds the given action.
168 @param action The action to add.
169 @returns True if the action was added.
170 */
171 public synchronized boolean addAction (ReportAction action) {
172 return m_ActionLoader.addModule (action);
173 }
174
175 /**
176 Adds the given transform.
177 @param transform The transform to add.
178 @returns True if the transform was added.
179 */
180 public synchronized boolean addTransform (ReportTransform transform) {
181 return m_TransformLoader.addModule (transform);
182 }
183
184 /**
185 Returns the path to the given DTD.
186 Just prepends the DTD base path to the DTD file name given.
187 */
188 public String getDTDPath (String dtd) {
189 return m_Environment.getDTDPath (dtd);
190 }
191
192 /** Returns the value of the given property, or null if it is not set. */
193 public String getProperty (String property) {
194 return m_Environment.getProperty (property);
195 }
196
197 /** Accesses the given resource. */
198 public InputStream getResource (String path) throws IOException {
199 return m_Environment.getResource (path);
200 }
201
202 /** Returns the environment object. */
203 public ReportEnvironment getEnvironment() {
204 return m_Environment;
205 }
206
207 /** Returns true if the given user is allowed to access the given module. */
208 public boolean canAccessModule (Module module, String user) {
209 if (module == null)
210 throw new NullPointerException();
211 if (m_Authorisation == null)
212 return true;
213 if (module instanceof Report)
214 return m_Authorisation.authorisedReport (module.getID(), user);
215 else if (module instanceof ReportAction)
216 return m_Authorisation.authorisedAction (module.getID(), user);
217 else if (module instanceof ReportTransform)
218 return m_Authorisation.authorisedTransform (module.getID(), user);
219 else
220 throw new IllegalArgumentException ("Module not report, action or transform: " + module.getClass().getName());
221 }
222
223 /**
224 Returns a configuration option fragment to select from the given modules.
225 @param modules The list of modules to select from.
226 @param id The ID of the select.
227 @param style The select style, must be one of SELECT_STYLE_RADIO, SELECT_STYLE_CHECK, or SELECT_STYLE_COMBO.
228 @param label The text to display for the select.
229 @param indent The level of indention.
230 */
231 public String createModuleSelect (List modules, String id, int style, String label, int indent) {
232 StringBuffer result = new StringBuffer();
233 openSelectTag (result, id, style, label, true, indent);
234 boolean first = true;
235 Iterator i = modules.iterator();
236 while (i.hasNext()) {
237 Module module = (Module) i.next();
238 addOptionTag (result, module.getID(), module.getName(), first, true, indent + 1);
239 first = false;
240 }
241 XMLConstructor.addIndent (result, indent);
242 result.append ("</SELECT>\n");
243 return result.toString();
244 }
245
246 /** Open a select tag. */
247 public static void openSelectTag (StringBuffer buffer, String id, int style, String label, boolean enabled, int indent) {
248 XMLConstructor.addIndent (buffer, indent);
249 buffer.append ("<SELECT");
250 XMLConstructor.addAttribute (buffer, "ID", id);
251 switch (style) {
252 case SELECT_STYLE_RADIO:
253 XMLConstructor.addAttribute (buffer, "Type", "radio");
254 break;
255 case SELECT_STYLE_CHECK:
256 XMLConstructor.addAttribute (buffer, "Type", "checkbox");
257 break;
258 case SELECT_STYLE_COMBO:
259 XMLConstructor.addAttribute (buffer, "Type", "combo");
260 break;
261 default:
262 throw new IllegalArgumentException ("Invalid select style " + style);
263 }
264 if (label != null && !label.equals (""))
265 XMLConstructor.addAttribute (buffer, "Label", label);
266 if (!enabled)
267 XMLConstructor.addAttribute (buffer, "Enabled", "no");
268 buffer.append (">\n");
269 }
270
271 /** Add an option tag. */
272 public static void addOptionTag (StringBuffer buffer, String id, String label, boolean selected, boolean enabled, int indent) {
273 XMLConstructor.addIndent (buffer, indent);
274 buffer.append ("<OPTION");
275 if (id != null)
276 XMLConstructor.addAttribute (buffer, "ID", id);
277 XMLConstructor.addAttribute (buffer, "Label", label);
278 if (selected)
279 XMLConstructor.addAttribute (buffer, "Selected", "yes");
280 if (!enabled)
281 XMLConstructor.addAttribute (buffer, "Enabled", "no");
282 buffer.append ("/>\n");
283 }
284
285 /**
286 Returns a list of all modules available to the given user.
287 @param loader The module loader to get the modules from.
288 @param user The authenticated user, or null if not authenticated
289 */
290 protected List getAvailableModules (ModuleLoader loader, String user) {
291
292 // Get all modules
293 List result = loader.getAvailableModules();
294
295 // Trim ones the user does not have access to
296 Iterator i = result.iterator();
297 while (i.hasNext()) {
298 if (!canAccessModule ((Module) i.next(), user))
299 i.remove();
300 }
301
302 // Return the rest
303 return result;
304 }
305
306 private AuthorisationManager m_Authorisation;
307 private ReportEnvironment m_Environment;
308 private ModuleLoader m_ReportLoader;
309 private ModuleLoader m_ActionLoader;
310 private ModuleLoader m_TransformLoader;
311 }