001/* 002 * $RCSfile: FacilityManager.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:25 $ 005 * $State: Exp $ 006 * 007 * Class: MsgLoggerManager 008 * 009 * Description: Manages common facilities across threads 010 * 011 * 012 * 013 * COPYRIGHT: 014 * 015 * This software module was originally developed by Raphaël Grosbois and 016 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel 017 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David 018 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research 019 * Centre France S.A) in the course of development of the JPEG2000 020 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This 021 * software module is an implementation of a part of the JPEG 2000 022 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio 023 * Systems AB and Canon Research Centre France S.A (collectively JJ2000 024 * Partners) agree not to assert against ISO/IEC and users of the JPEG 025 * 2000 Standard (Users) any of their rights under the copyright, not 026 * including other intellectual property rights, for this software module 027 * with respect to the usage by ISO/IEC and Users of this software module 028 * or modifications thereof for use in hardware or software products 029 * claiming conformance to the JPEG 2000 Standard. Those intending to use 030 * this software module in hardware or software products are advised that 031 * their use may infringe existing patents. The original developers of 032 * this software module, JJ2000 Partners and ISO/IEC assume no liability 033 * for use of this software module or modifications thereof. No license 034 * or right to this software module is granted for non JPEG 2000 Standard 035 * conforming products. JJ2000 Partners have full right to use this 036 * software module for his/her own purpose, assign or donate this 037 * software module to any third party and to inhibit third parties from 038 * using this software module for non JPEG 2000 Standard conforming 039 * products. This copyright notice must be included in all copies or 040 * derivative works of this software module. 041 * 042 * Copyright (c) 1999/2000 JJ2000 Partners. 043 * 044 * 045 * 046 */ 047 048 049package jj2000.j2k.util; 050 051import java.util.Collections; 052import java.util.Map; 053import java.util.WeakHashMap; 054 055/** 056 * This class manages common facilities for mutithreading environments, It can 057 * register different facilities for each thread, and also a default one, so 058 * that they can be referred by static methods, while possibly having 059 * different ones for different threads. Also a default facility exists that 060 * is used for threads for which no particular facility has been registerd 061 * registered. 062 * 063 * <P>Currently the only kind of facilities managed is MsgLogger. 064 * 065 * <P>An example use of this class is if 2 instances of a decoder are running 066 * in different threads and the messages of the 2 instances should be 067 * separated. 068 * 069 * <P>The default MsgLogger is a StreamMsgLogger that uses System.out as 070 * the 'out' stream and System.err as the 'err' stream, and a line width of 071 * 78. This can be changed using the registerMsgLogger() method. 072 * 073 * @see MsgLogger 074 * 075 * @see StreamMsgLogger 076 * */ 077public class FacilityManager { 078 079 private static final StreamMsgLogger DEFAULT_LOGGER = new StreamMsgLogger(System.out,System.err,78); 080 081 /** The loggers associated to different threads */ 082 private final static Map<Thread, MsgLogger> loggerList = 083 Collections.synchronizedMap(new WeakHashMap<Thread, MsgLogger>()); 084 085 /** The default logger, for threads that have none associated with them */ 086 private static volatile MsgLogger defMsgLogger = DEFAULT_LOGGER; 087 088 /** The ProgressWatch instance associated to different threads */ 089 private final static Map<Thread, ProgressWatch> watchProgList = 090 Collections.synchronizedMap(new WeakHashMap<Thread, ProgressWatch>()); 091 092 /** The default ProgressWatch for threads that have none 093 * associated with them. */ 094 private static volatile ProgressWatch defWatchProg = null; 095 096 /** 097 * Register the ProgressWatch for the given thread. 098 * <p> 099 * If any other logging facility was registered with the 100 * given thread, it is overridden. If the Thread is null then 'ml' is taken 101 * as the default message logger that is used for threads that have no 102 * ProgressWatch registered. 103 * <p> 104 * To unregister, use {@link #unregisterProgressWatch(Thread)} 105 * 106 * @param t The thread to associate with progress watcher 107 * @param pw The ProgressWatch to associate with thread 108 * 109 */ 110 public static void registerProgressWatch(Thread t,ProgressWatch pw) { 111 if(pw==null) { 112 throw new NullPointerException(); 113 } 114 if(t==null) { 115 defWatchProg = pw; 116 } 117 else { 118 watchProgList.put(t,pw); 119 } 120 } 121 122 /** 123 * Unregister the ProgressWatch previously registered for the given thread. 124 * <p> 125 * If t is null, the default progress watch is unregistered. 126 * 127 * @see #registerProgressWatch(Thread, ProgressWatch) 128 * @param t 129 * Thread to unregister progress watch for, or <code>null</code> 130 * to unregister the default progress watch. 131 */ 132 public static void unregisterProgressWatch(Thread t) { 133 if (t == null) { 134 defWatchProg = null; 135 } else { 136 watchProgList.remove(t); 137 } 138 } 139 140 /** 141 * Return the ProgressWatch instance registered with the current 142 * thread (the thread that calls this method). If the current 143 * thread has no registered ProgressWatch, then the default one is used. 144 * 145 * @see #registerProgressWatch(Thread, ProgressWatch) 146 * */ 147 public static ProgressWatch getProgressWatch() { 148 ProgressWatch pw = (ProgressWatch) 149 watchProgList.get(Thread.currentThread()); 150 return (pw==null) ? defWatchProg : pw; 151 } 152 153 /** 154 * Register MsgLogger 'ml' as the logging facility of the given thread. 155 * <p> 156 * If any other logging facility was registered with the thread, it is 157 * overriden. If the Thread is <code>null</code>, then the given message 158 * logger will be set as the default for threads that have no MsgLogger 159 * registered. 160 * 161 * @see #unregisterMsgLogger(Thread) 162 * @param t 163 * The thread to associate a MsgLogger for 164 * @param ml 165 * The MsgLogger to associate 166 * */ 167 public static void registerMsgLogger(Thread t, MsgLogger ml) { 168 if (ml == null) { 169 throw new NullPointerException(); 170 } 171 if (t == null) { 172 defMsgLogger = ml; 173 } 174 else { 175 loggerList.put(t,ml); 176 } 177 } 178 179 /** 180 * Unregister the MsgLogger previously registered for the given thread. 181 * <p> 182 * If the Thread is <code>null</code>, then the default logger is reset to a 183 * {@link StreamMsgLogger} using {@link System#out} and {@link System#err}. 184 * 185 * @see #registerMsgLogger(Thread, MsgLogger) 186 * 187 * @param t 188 * The thread to remove the MsgLogger for, or <code>null</code> 189 * to reset the default message logger. 190 */ 191 public static void unregisterMsgLogger(Thread t) { 192 if (t == null) { 193 defMsgLogger = DEFAULT_LOGGER; 194 } else { 195 loggerList.remove(t); 196 } 197 } 198 199 /** 200 * Return the MsgLogger registered with the current thread (the thread that 201 * calls this method). 202 * <p> 203 * If the current thread has no registered {@link MsgLogger} then the default 204 * message logger is returned. 205 * 206 * @see #registerMsgLogger(Thread, MsgLogger) 207 * @see #getMsgLogger(Thread) 208 * @return The MsgLogger registered for the current thread, or the default 209 * one if there is none registered for it. 210 * 211 * 212 * */ 213 public static MsgLogger getMsgLogger() { 214 MsgLogger ml = 215 (MsgLogger) loggerList.get(Thread.currentThread()); 216 return (ml == null) ? defMsgLogger : ml; 217 } 218 219 /** 220 * Return the MsgLogger registered with the thread 't'. 221 * <p> 222 * If the thread 't' has no registered {@link MsgLogger}, then the default 223 * message logger is returned. 224 * 225 * @param t 226 * The thread for which to return the MsgLogger 227 * @return The MsgLogger registered for the current thread, or the default 228 * one if there is none registered for it. 229 */ 230 public static MsgLogger getMsgLogger(Thread t) { 231 MsgLogger ml = 232 (MsgLogger) loggerList.get(t); 233 return (ml == null) ? defMsgLogger : ml; 234 } 235}