2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with any library licensed under the Apache Software License,
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23 * (or with modified versions of the above that use the same license as the above),
24 * and distribute linked combinations including the two. You must obey the
25 * GNU General Public License in all respects for all of the code used other than
26 * the above mentioned libraries. If you modify this file, you may extend this
27 * exception to your version of the file, but you are not obligated to do so.
28 * If you do not wish to do so, delete this exception statement from your version.
31 package mircoders.global;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
39 import mir.bundle.BasicBundleFactory;
40 import mir.bundle.BundleFactory;
41 import mir.bundle.CascadingBundleFactory;
42 import mir.bundle.PropertiesFileBundleLoader;
43 import mir.config.MirPropertiesConfiguration;
44 import mir.entity.adapter.EntityAdapter;
45 import mir.log.LoggerEngine;
46 import mir.log.LoggerWrapper;
47 import mir.misc.ConfigException;
48 import mircoders.accesscontrol.AccessControl;
49 import mircoders.entity.EntityComment;
50 import mircoders.entity.EntityContent;
51 import mircoders.entity.EntityUsers;
52 import mircoders.localizer.MirAdminInterfaceLocalizer;
53 import mircoders.localizer.MirCachingLocalizerDecorator;
54 import mircoders.localizer.MirLocalizer;
55 import mircoders.localizer.MirLocalizerExc;
57 public class MirGlobal {
58 static private MirLocalizer localizer;
59 static private ProducerEngine producerEngine;
60 static private Abuse abuse;
61 static private MRUCache mruCache;
62 static private AccessControl accessControl;
63 static private Map articleOperations;
64 static private Map commentOperations;
65 static private Map loggedInUsers = new HashMap();
66 static private Map loggedInUserIds = new HashMap();
67 static private LoggerWrapper logger = new LoggerWrapper("Global");
68 static private LoggerWrapper adminUsageLogger = new LoggerWrapper("AdminUsage");
69 // static private ChangeEngine changeEngine = new ChangeEngine();
70 static private DatabaseEngine databaseEngine;
72 static private BundleFactory bundleFactory =
73 new CascadingBundleFactory(
74 new BasicBundleFactory(
75 new PropertiesFileBundleLoader(
76 config().getHome())));
78 public synchronized static MirLocalizer localizer() {
79 String localizerClassName;
82 if (localizer == null ) {
83 localizerClassName = config().getString("Mir.Localizer", "mirlocal.localizer.basic.MirBasicLocalizer");
86 localizerClass = Class.forName(localizerClassName);
89 throw new ConfigException("localizer class '" +
90 localizerClassName + "' not found: " + t.toString());
93 if (!(MirLocalizer.class.isAssignableFrom(localizerClass)))
94 throw new ConfigException("localizer class '" +
95 localizerClassName + "' is not assignable from MirLocalizer");
98 localizer = new MirCachingLocalizerDecorator((MirLocalizer) localizerClass.newInstance());
100 catch (Throwable t) {
101 throw new ConfigException("localizer class '" +
102 localizerClassName + "' cannot be instantiated: " + t.toString());
110 * Returns a string that provides some global status information
112 public static String getStatus() {
113 StringBuffer result = new StringBuffer();
115 result.append((Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/(1024*1024));
116 result.append("M in use, ");
117 result.append(Thread.activeCount()).append(" threads, ");
118 result.append(getDatabaseEngine().getStatus());
120 return result.toString();
123 public synchronized static Abuse abuse() {
126 abuse = new Abuse(localizer().dataModel().adapterModel());
128 catch (MirLocalizerExc e) {
129 throw new RuntimeException(e.getMessage());
137 * returns the global change engine (used to track changed files)
139 // public static ChangeEngine getChangeEngine() {
140 // return changeEngine;
143 public static MirPropertiesConfiguration config() {
144 return MirPropertiesConfiguration.instance();
147 public synchronized static DatabaseEngine getDatabaseEngine() {
148 if (databaseEngine==null)
149 databaseEngine = new DatabaseEngine();
151 return databaseEngine;
154 public static ProducerEngine getProducerEngine() {
155 if (producerEngine == null) {
156 producerEngine = new ProducerEngine();
159 return producerEngine;
162 public static MRUCache mruCache() {
163 synchronized(MirGlobal.class) {
164 if (mruCache == null) {
165 mruCache = new MRUCache();
171 public static synchronized AccessControl accessControl() {
172 if (accessControl == null) {
173 accessControl=new AccessControl();
176 return accessControl;
179 public static void performArticleOperation(EntityUsers aUser, EntityContent anArticle, String anOperation) {
180 MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation = getArticleOperationForName(anOperation);
183 EntityAdapter user = null;
185 user = localizer().dataModel().adapterModel().makeEntityAdapter("user", aUser);
190 localizer().dataModel().adapterModel().makeEntityAdapter("content", anArticle));
192 catch (Throwable t) {
193 t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
195 throw new RuntimeException(t.toString());
199 public static void performCommentOperation(EntityUsers aUser, EntityComment aComment, String anOperation) {
200 MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation = getCommentOperationForName(anOperation);
203 EntityAdapter user = null;
205 user = localizer().dataModel().adapterModel().makeEntityAdapter("user", aUser);
210 localizer().dataModel().adapterModel().makeEntityAdapter("comment", aComment));
212 catch (Throwable t) {
213 throw new RuntimeException(t.toString());
217 private synchronized static MirAdminInterfaceLocalizer.MirSimpleEntityOperation
218 getArticleOperationForName(String aName) {
220 if (articleOperations == null) {
221 articleOperations = new HashMap();
222 Iterator i = localizer().adminInterface().simpleArticleOperations().iterator();
223 while (i.hasNext()) {
224 MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =
225 (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();
226 articleOperations.put(operation.getName(), operation);
230 return (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) articleOperations.get(aName);
232 catch (Throwable t) {
233 throw new RuntimeException(t.toString());
237 private synchronized static MirAdminInterfaceLocalizer.MirSimpleEntityOperation
238 getCommentOperationForName(String aName) {
240 if (commentOperations == null) {
241 commentOperations = new HashMap();
242 Iterator i = localizer().adminInterface().simpleCommentOperations().iterator();
243 while (i.hasNext()) {
244 MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =
245 (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();
246 commentOperations.put(operation.getName(), operation);
250 return (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) commentOperations.get(aName);
252 catch (Throwable t) {
253 throw new RuntimeException(t.toString());
257 public static boolean isUserLoggedIn(String anId) {
258 synchronized (loggedInUserIds) {
259 return loggedInUserIds.containsKey(anId);
263 public static List getLoggedInUsers() {
264 List result = new ArrayList();
266 synchronized (loggedInUsers) {
267 Iterator i = loggedInUsers.entrySet().iterator();
269 while (i.hasNext()) {
270 Map.Entry entry = (Map.Entry) i.next();
272 Map item = new HashMap();
273 item.put("name", entry.getKey());
274 item.put("count", entry.getValue());
282 public static BundleFactory getBundleFactory() {
283 return bundleFactory;
286 public static void registerLogin(String aName, String anId) {
287 modifyLoggedInCount(aName, anId, 1);
290 public static void registerLogout(String aName, String anId) {
291 modifyLoggedInCount(aName, anId, -1);
294 private static void modifyLoggedInCount(String aName, String anId, int aModifier) {
295 synchronized (loggedInUsers) {
296 Integer count = (Integer) loggedInUsers.get(aName);
298 count = new Integer(0);
300 if (count.intValue()+aModifier<=0) {
301 loggedInUsers.remove(aName);
304 loggedInUsers.put(aName, new Integer(count.intValue() + aModifier));
308 synchronized (loggedInUserIds) {
309 Integer count = (Integer) loggedInUserIds.get(anId);
311 count = new Integer(0);
313 if (count.intValue()+aModifier<=0) {
314 loggedInUserIds.remove(anId);
317 loggedInUserIds.put(anId, new Integer(count.intValue() + aModifier));
323 * Called whenever a modifying admin action occurs. Used to log
324 * the action, if admin activity logging is turned on,
326 public static void logAdminUsage(EntityUsers aUser, String anObject, String aDescription) {
328 if (config().getString("Mir.Admin.LogAdminActivity", "0").equals("1")) {
329 String user = "unknown (" + aUser.toString() + ")";
331 user = aUser.getFieldValue("login");
332 adminUsageLogger.info(user + " | " + anObject + " | " + aDescription);
335 catch (Throwable t) {
336 logger.error("Error while logging admin usage ("+
337 aUser.toString()+", "+aDescription+"): " +t.toString());
342 * Reloads all reloadable configurations, such as the producer subsystem.
344 public static void reloadConfigurations() throws MirGlobalExc, MirGlobalFailure {
345 getProducerEngine().reloadConfiguration();
347 LoggerEngine.reload();
349 catch (Throwable e) {
350 throw new MirGlobalFailure(e);
352 getBundleFactory().reload();