001package lombok.launch;
002
003import java.lang.reflect.InvocationTargetException;
004import java.lang.reflect.Method;
005import java.io.File;
006import java.io.IOException;
007import java.util.List;
008import java.util.Map;
009
010/**
011 * Since the Shadow Class Loader hides Lombok's internal Delombok, we need to access it via reflection.
012 *
013 * @see <a href="https://github.com/rzwitserloot/lombok/blob/master/src/delombok/lombok/delombok/Delombok.java">lombok.delombok.Delombok</a>
014 */
015public class Delombok {
016
017    private final Object delombokInstance;
018
019    private final Method addDirectory;
020    private final Method delombok;
021    private final Method formatOptionsToMap;
022    private final Method setVerbose;
023    private final Method setCharset;
024    private final Method setClasspath;
025    private final Method setFormatPreferences;
026    private final Method setOutput;
027    private final Method setSourcepath;
028
029    public Delombok () throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
030        final ClassLoader shadowClassLoader = Main.getShadowClassLoader();
031        final Class<?> delombokClass = shadowClassLoader.loadClass("lombok.delombok.Delombok");
032        this.delombokInstance = delombokClass.getDeclaredConstructor().newInstance();
033        // Get method handles...
034        this.addDirectory = delombokClass.getMethod("addDirectory", File.class);
035        this.delombok = delombokClass.getMethod("delombok");
036        this.formatOptionsToMap = delombokClass.getMethod("formatOptionsToMap", List.class);
037        this.setVerbose = delombokClass.getMethod("setVerbose", boolean.class);
038        this.setCharset = delombokClass.getMethod("setCharset", String.class);
039        this.setClasspath = delombokClass.getMethod("setClasspath", String.class);
040        this.setFormatPreferences = delombokClass.getMethod("setFormatPreferences", Map.class);
041        this.setOutput = delombokClass.getMethod("setOutput", File.class);
042        this.setSourcepath = delombokClass.getMethod("setSourcepath", String.class);
043    }
044
045    public void addDirectory (final File base) throws IllegalAccessException, IOException, InvocationTargetException {
046        addDirectory.invoke(delombokInstance, base);
047    }
048
049    public boolean delombok () throws IllegalAccessException, IOException, InvocationTargetException {
050        return Boolean.parseBoolean( delombok.invoke(delombokInstance).toString() );
051    }
052
053    @SuppressWarnings("unchecked")
054    public Map<String, String> formatOptionsToMap (final List<String> formatOptions) throws Exception {
055        return (Map<String, String>)formatOptionsToMap.invoke(null, formatOptions);
056    }
057
058    public void setVerbose (final boolean verbose) throws IllegalAccessException, InvocationTargetException {
059        setVerbose.invoke(delombokInstance, verbose);
060    }
061
062    public void setCharset (final String charset) throws IllegalAccessException, InvocationTargetException {
063        setCharset.invoke(delombokInstance, charset);
064    }
065
066    public void setClasspath (final String classpath) throws IllegalAccessException, InvocationTargetException {
067        setClasspath.invoke(delombokInstance, classpath);
068    }
069
070    public void setFormatPreferences (final Map<String, String> prefs) throws IllegalAccessException, InvocationTargetException {
071        setFormatPreferences.invoke(delombokInstance, prefs);
072    }
073
074    public void setOutput (final File dir) throws IllegalAccessException, InvocationTargetException {
075        setOutput.invoke(delombokInstance, dir);
076    }
077
078    public void setSourcepath (final String sourcepath) throws IllegalAccessException, InvocationTargetException {
079        setSourcepath.invoke(delombokInstance, sourcepath);
080    }
081}