Source code: org/scoja/common/PriorityUtils.java
1
2 package org.scoja.common;
3
4 import java.util.*;
5 import java.text.ParseException;
6
7
8 /**
9 * This a utility class to work with Syslog priorities.
10 * Contains named constants for facilities and levels.
11 * It has serveral methods to convert between priority integers and strings.
12 */
13 public abstract class PriorityUtils {
14
15 //======================================================================
16 // LEVELS:
17
18 /** To use when we a level is needed but we have no sensible
19 * level value. */
20 public static final int UNKNOWN_LEVEL = -1;
21
22 /** Level: System is unusable. */
23 public static final int EMERG = 0;
24 /** Level: Action must be taken immediately */
25 public static final int ALERT = 1;
26 /** Level: Critical conditions */
27 public static final int CRIT = 2;
28 /** Level: Error conditions */
29 public static final int ERR = 3;
30 /** Level: Warning conditions */
31 public static final int WARNING = 4;
32 /** Level: Normal but significant condition */
33 public static final int NOTICE = 5;
34 /** Level: Informational */
35 public static final int INFO = 6;
36 /** Level: Debug-level messages */
37 public static final int DEBUG = 7;
38
39 /** Current number of levels. */
40 public static final int TOTAL_LEVELS = 8;
41
42
43 //======================================================================
44 // FACILITIES:
45
46 /** To use when we a facility is needed but we have no sensible
47 * facility value. */
48 public static final int UNKNOWN_FACILITY = -1;
49
50 /** Facility: Kernel messages */
51 public static final int KERN = 0;
52 /** Facility: Random user-level messages */
53 public static final int USER = 1;
54 /** Facility: Mail system */
55 public static final int MAIL = 2;
56 /** Facility: System daemons */
57 public static final int DAEMON = 3;
58 /** Facility: Security/authorization messages */
59 public static final int AUTH = 4;
60 /** Facility: Messages generated internally by syslogd */
61 public static final int SYSLOG = 5;
62 /** Facility: Line printer subsystem */
63 public static final int LPR = 6;
64 /** Facility: Network news subsystem */
65 public static final int NEWS = 7;
66 /** Facility: UUCP subsystem */
67 public static final int UUCP = 8;
68 /** Facility: Clock daemon */
69 public static final int CRON = 9;
70 /** Facility: Security/authorization messages (private) (Linux) */
71 public static final int AUTHPRIV = 10;
72 /** Facility: Ftp daemon (Linux) */
73 public static final int FTP = 11;
74
75 /* Codes from 12 upto 15 are reserved for system use */
76
77 /** Facility: Reserved for local use */
78 public static final int LOCAL0 = 16;
79 /** Facility: Reserved for local use */
80 public static final int LOCAL1 = 17;
81 /** Facility: Reserved for local use */
82 public static final int LOCAL2 = 18;
83 /** Facility: Reserved for local use */
84 public static final int LOCAL3 = 19;
85 /** Facility: Reserved for local use */
86 public static final int LOCAL4 = 20;
87 /** Facility: Reserved for local use */
88 public static final int LOCAL5 = 21;
89 /** Facility: Reserved for local use */
90 public static final int LOCAL6 = 22;
91 /** Facility: Reserved for local use */
92 public static final int LOCAL7 = 23;
93
94 /* Current number of facilities */
95 public static final int TOTAL_FACILITIES = 24;
96
97
98 //======================================================================
99 // PRIORITIES:
100
101 /** To use when we a priority is needed but we have no sensible
102 * priority value. */
103 public static final int UNKNOWN_PRIORITY = -1;
104
105 public static final int DEFAULT_PRIORITY = buildPriority(USER,NOTICE);
106
107 /** Mask to extract level part from a priority. */
108 public static final int LEVEL_MASK = 0x07;
109
110 /** Mask to extract facility part from a priority (previous to
111 * shift with {@link #FACILITY_SHIFT}. */
112 public static final int FACILITY_MASK = 0x03F8;
113
114 /** Shift to apply to a priority to get its facility. */
115 public static final int FACILITY_SHIFT = 3;
116
117
118 //======================================================================
119 // NAMES:
120
121 /**
122 * All level names, sorted according theirs level number.
123 * Some levels have more than one name; this is why we have a matrix
124 * instead of a vector.
125 * The first name is the modern one; the rest are deprecated names.
126 */
127 private static String[][] levelNames = {
128 {"emerg", "panic"}, // 0
129 {"alert"}, // 1
130 {"crit"}, // 2
131 {"err", "error"}, // 3
132 {"warning", "warn"}, // 4
133 {"notice"}, // 5
134 {"info"}, // 6
135 {"debug"}, // 7
136 };
137
138 /**
139 * All facilities names, sorted according theirs facility number.
140 * Facilities between {@link #FTP} and {@link #LOCAL0} have no name;
141 * so this array contains <code>null</code> at these positions.
142 */
143 private static String[] facilityNames = {
144 "kern", // 0
145 "user", // 1
146 "mail", // 2
147 "daemon", // 3
148 "auth", // 4
149 "syslog", // 5
150 "lpr", // 6
151 "news", // 7
152 "uucp", // 8
153 "cron", // 9
154 "authpriv", // 10
155 "ftp", // 11
156 null, // 12
157 null, // 13
158 null, // 14
159 null, // 15
160 "local0", // 16
161 "local1", // 17
162 "local2", // 18
163 "local3", // 19
164 "local4", // 20
165 "local5", // 21
166 "local6", // 22
167 "local7", // 23
168 "security" // Deprecated
169 };
170
171
172 /**
173 * A table to convert from level name to level value.
174 * It is a mapping from String to Integer.
175 * It is filled with values from {@link #levelNames}.
176 */
177 private static Map name2level;
178 static {
179 name2level = new HashMap(levelNames.length);
180 for (int i = 0; i < levelNames.length; i++) {
181 for (int j = 0; j < levelNames[i].length; j++) {
182 name2level.put(levelNames[i][j], new Integer(i));
183 }
184 }
185 }
186
187 /**
188 * A table to convert from facility name to facility value;
189 * It is a mapping from String to Integer.
190 * It is filled with non null entries of {@link #facilityNames}.
191 */
192 private static Map name2facility;
193 static {
194 name2facility = new HashMap(facilityNames.length);
195 for (int i = 0; i < facilityNames.length; i++) {
196 if (facilityNames[i] != null) {
197 name2facility.put(facilityNames[i], new Integer(i));
198 }
199 }
200 }
201
202
203 //======================================================================
204 // METHODS:
205
206 /**
207 * Return the facility part of a priority.
208 */
209 static public int getFacility(final int priority) {
210 return (priority & FACILITY_MASK) >> FACILITY_SHIFT;
211 }
212
213 /**
214 * Return the level part of a priority.
215 */
216 static public int getLevel(final int priority) {
217 return priority & LEVEL_MASK;
218 }
219
220 /**
221 * Builds a priority from a facility and a level.
222 */
223 static public int buildPriority(final int facility, final int level) {
224 return (facility << 3) | level;
225 }
226
227 /**
228 * Return the name of <code>facility</code> if it is known;
229 * <code>null</code> otherwise.
230 */
231 static public String getFacilityName(final int facility) {
232 return (0 <= facility && facility < TOTAL_FACILITIES)
233 ? facilityNames[facility] : null;
234 }
235
236 /**
237 * Return the name of <code>level</code> if it is known;
238 * <code>null</code> otherwise.
239 */
240 static public String getLevelName(final int level) {
241 return (0 <= level && level < TOTAL_LEVELS)
242 ? levelNames[level][0] : null;
243 }
244
245 /**
246 * Return the name of <code>priority</code> if both its facility
247 * and level are known; <code>null</code> otherwise.
248 */
249 static public String getPriorityName(final int priority) {
250 final String facilityName = getFacilityName(getFacility(priority));
251 if (facilityName == null) return null;
252 final String levelName = getLevelName(getLevel(priority));
253 if (levelName == null) return null;
254 return facilityName + "." + levelName;
255 }
256
257 /**
258 * Compares <code>facility</code> against known facility names
259 * and returns it corresponding facility number.
260 * Capitalization is irrelevant.
261 * If <code>facility</code> is not a know facility name, returns -1.
262 */
263 static public int parseFacility(final String facility) {
264 final String key = facility.toLowerCase();
265 final Integer value = (Integer)name2facility.get(key);
266 return (value != null) ? value.intValue() : UNKNOWN_FACILITY;
267 }
268
269 /**
270 * Compares <code>level</code> against known level names
271 * and returns it corresponding level number.
272 * Capitalization is irrelevant.
273 * @throws ParseException if <code>facility</code> is not a know
274 * level name.
275 */
276 static public int parseLevel(final String level) {
277 final String key = level.toLowerCase();
278 final Integer value = (Integer)name2level.get(key);
279 return (value != null) ? value.intValue() : UNKNOWN_LEVEL;
280 }
281
282 /**
283 * Tries to build a priority number from its string description at
284 * <code>priority</code>.
285 *
286 */
287 static public int parsePriority(final String priority) {
288 try {
289 return Integer.parseInt(priority);
290 } catch(NumberFormatException e) {}
291
292 final int dotIdx = priority.indexOf('.');
293 if (dotIdx == -1) {
294 final int facility = parseFacility(priority);
295 if (facility != UNKNOWN_FACILITY) {
296 return buildPriority(facility, NOTICE);
297 }
298 final int level = parseLevel(priority);
299 if (level != UNKNOWN_LEVEL) {
300 return buildPriority(USER, level);
301 }
302 } else {
303 final int facility = parseFacility(priority.substring(0, dotIdx));
304 final int level = parseLevel(priority.substring(dotIdx+1));
305 if (facility != UNKNOWN_FACILITY && level != UNKNOWN_LEVEL) {
306 buildPriority(facility,level);
307 }
308 }
309 return UNKNOWN_PRIORITY;
310 }
311
312 }