emreturka
emreturka

Reputation: 876

Parsing a Java class for replace

I must replace all off e.printStackTrace(); with logger. But there are about 2000 class. I can replace all in Eclipse but I have to define Logger for all class. Is there any solutions that you advice?

Upvotes: 1

Views: 113

Answers (3)

ug_
ug_

Reputation: 11440

Beyond doing a CTRL+H and locating all e.printStackTrace(); and replacing them, you could take an alternative tack by creating a logger factory.

public class LoggingFactory {
    private static LoggingFactory instance;
    private Map<Class, Logger> loggers;

    public static synchronized LoggingFactory getInstance() {
        if(instance == null) {
            instance = new LoggingFactory();
        }
        return instance;
    }

    public static Logger getLogger(Class clazz) {
        synchronized (clazz) {
            if(getInstance().loggers.get(clazz) == null) {
                getInstance().loggers.put(clazz, Logger.getLogger(clazz.getName()));
            }
            return getInstance().loggers.get(clazz);
        }
    }
}

Using this class you can do a global search and replace for some regex like

([\w\d]+)\.printStackTrace\(\);

and replace it with

LoggingFactory.getLogger(this.getClass()).error($1);

when doing this make sure you look closely at the options the popup provies and have the regex checkboxes selected!


The result would be something like this

e2.printStackTrace(); becomes LoggingFactory.getLogger(this.getClass()).error(e2);

Now this will still leave some errors in places where static methods had been replaced but you can go back and fix those ones manually.


Edit

I feel kinda dumb here but I realized after looking at this question again that most logging APIs are already built upon a factory design. The answer above is still valid and might benefit you if your using a custom Logger or if their method for getting/creating a logger is not sufficient for a regular expression replace.

So if you are using log4j you could simply make this regex to replace instead and not use the LoggingFactory:

org.apache.log4j.Logger.getLogger(this.getClass()).error($1);

Upvotes: 3

David M. Karr
David M. Karr

Reputation: 15205

If none of these other responses help, I can give you another idea which will definitely solve the problem, but it might require too much pre-work for your tastes.

My best answer to problems like this can be summed up in one word: Emacs

I use Eclipse for all my day-to-day coding tasks, but every once in a while I run into a mutant task that requires a powerful scripting environment that also understands the syntax of the files I'm operating on.

For a problem like this, I can easily see the potential of recording a keyboard macro that does something like this:

I first prepare a list of search occurrences for the things I want to operate on, in this case being one line from every class with a printStackTrace call.

  1. Search backwards for class declaration
  2. Save base class name to clipboard
  3. Search forward for opening brace.
  4. Insert newline.
  5. Insert "public static .... ", along with pasting in the clipboard.
  6. Modify resulting line, as long as it's in a way that will work for all occurrences.
  7. Save file.
  8. Go to the next search occurrence.

Stop recording the macro. Now repeat the macro 999999 times (it stops on end of input). You've now defined all of your Logger objects.

It can sometimes be tricky to figure out the correct steps to follow, but once you get used to this, you can do some amazing mass transformations.

Now you might be able to do a global replace of your "printStackTrace()" calls.

Upvotes: 0

Ben
Ben

Reputation: 3518

replace e.printStackTrace(); with com.class.path.to.static.Logger.doLog(e);

Upvotes: 0

Related Questions