001    package hirondelle.web4jtools.webmaster.logging;
002    
003    import hirondelle.web4j.action.ActionTemplateListAndEdit;
004    import hirondelle.web4j.action.ResponsePage;
005    import hirondelle.web4j.database.DAOException;
006    import hirondelle.web4j.request.RequestParameter;
007    import hirondelle.web4j.request.RequestParser;
008    import hirondelle.web4j.util.Consts;
009    import hirondelle.web4j.util.Util;
010    
011    import java.util.Enumeration;
012    import java.util.Map;
013    import java.util.TreeMap;
014    import java.util.logging.Level;
015    import java.util.logging.LogManager;
016    import java.util.logging.Logger;
017    
018    /**
019    * List all JRE loggers, and allow changes to logging levels. 
020    */
021    public final class EditLoggerLevels extends ActionTemplateListAndEdit {
022    
023      /** Constructor. */
024      public EditLoggerLevels(RequestParser aRequestParser) {
025        super(FORWARD, REDIRECT, aRequestParser);
026      }
027    
028      public static final RequestParameter LOGGER_NAME = RequestParameter.withLengthCheck("Name");
029      public static final RequestParameter LEVEL = RequestParameter.withRegexCheck("Level",
030        "(ALL|INHERIT FROM PARENT|SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST|OFF)");
031    
032      /** List all JRE {@link Logger}s. */
033      protected void doList() throws DAOException {
034        addToRequest(ITEMS_FOR_LISTING, getLoggerNamesAndLevels());
035      }
036    
037      /** Ensure user input makes sense. */
038      protected void validateUserInput() {
039        fLoggerName = getParamUnsafe(LOGGER_NAME);
040        if (fLoggerName == null) {
041          fLoggerName = ROOT_LOGGER;
042        }
043        String loggerLevel = getParamUnsafe(LEVEL);
044        if (!Util.textHasContent(loggerLevel)) {
045          addError("Logger Level must be specified");
046        }
047        else {
048          if ("INHERIT FROM PARENT".equals(loggerLevel)) {
049            fLevel = null;
050          }
051          else {
052            try {
053              fLevel = Level.parse(loggerLevel);
054            }
055            catch (IllegalArgumentException ex) {
056              addError("Cannot parse input into a valid Level.");
057            }
058          }
059        }
060      }
061    
062      /** Fetch a {@link Logger} in preparation for editing its level. */
063      protected void attemptFetchForChange() throws DAOException {
064        String loggerName = getParamUnsafe(LOGGER_NAME);
065        if (loggerName == null) {
066          loggerName = ROOT_LOGGER;
067        }
068        LogManager manager = LogManager.getLogManager();
069        Logger logger = manager.getLogger(loggerName);
070        if (logger != null) {
071          addToRequest(ITEM_FOR_EDIT, logger);
072        }
073      }
074    
075      /** Update the logging level for a single {@link Logger}. */
076      protected void attemptChange() throws DAOException {
077        LogManager manager = LogManager.getLogManager();
078        Logger logger = manager.getLogger(fLoggerName);
079        logger.setLevel(fLevel);
080      }
081    
082      /** Not supported. */
083      protected void attemptAdd() throws DAOException {
084        throw new UnsupportedOperationException();
085      }
086    
087      /** Not supported. */
088      protected void attemptDelete() throws DAOException {
089        throw new UnsupportedOperationException();
090      }
091    
092      // PRIVATE //
093      private static final ResponsePage FORWARD = new ResponsePage("Loggers", "view.jsp", EditLoggerLevels.class);
094      private static final ResponsePage REDIRECT = new ResponsePage("EditLoggerLevels.do?Operation=List");
095      private String fLoggerName;
096      private Level fLevel;
097      private static final String ROOT_LOGGER = Consts.EMPTY_STRING;
098    
099      private Map<String, Logger> getLoggerNamesAndLevels() {
100        Map<String, Logger> result = new TreeMap<String, Logger>(String.CASE_INSENSITIVE_ORDER); // sorts alphabetically
101        LogManager logManager = LogManager.getLogManager();
102        Enumeration loggerNames = logManager.getLoggerNames();
103        while (loggerNames.hasMoreElements()) {
104          String loggerName = (String)loggerNames.nextElement();
105          Logger logger = logManager.getLogger(loggerName);
106          result.put(loggerName, logger);
107        }
108        return result;
109      }
110    }