/* * Copyright (C) 2014 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package de.plushnikov.intellij.lombok.patcher.inject; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.nio.charset.Charset; public class ClassRootFinder { private static String urlDecode(String in, boolean forceUtf8) { try { return URLDecoder.decode(in, forceUtf8 ? "UTF-8" : Charset.defaultCharset().name()); } catch (UnsupportedEncodingException e) { try { return URLDecoder.decode(in, "UTF-8"); } catch (UnsupportedEncodingException e1) { return in; } } } public static String findClassRootOfSelf() { return findClassRootOfClass(ClassRootFinder.class); } public static String findClassRootOfClass(Class<?> context) { String name = context.getName(); int idx = name.lastIndexOf('.'); String packageBase = ""; if (idx > -1) { packageBase = name.substring(0, idx); name = name.substring(idx + 1); } URL selfURL = context.getResource(name + ".class"); String self = selfURL.toString(); if (self.startsWith("file:/")) { String path = urlDecode(self.substring(5), false); if (!new File(path).exists()) { path = urlDecode(self.substring(5), true); } String suffix = "/" + packageBase.replace('.', '/') + "/" + name + ".class"; if (!path.endsWith(suffix)) { throw new IllegalArgumentException("Unknown path structure: " + path); } self = path.substring(0, path.length() - suffix.length()); } else if (self.startsWith("jar:")) { int sep = self.indexOf('!'); if (sep == -1) { throw new IllegalArgumentException("No separator in jar protocol: " + self); } String jarLoc = self.substring(4, sep); if (jarLoc.startsWith("file:/")) { String path = urlDecode(jarLoc.substring(5), false); if (!new File(path).exists()) { path = urlDecode(jarLoc.substring(5), true); } self = path; } else { throw new IllegalArgumentException("Unknown path structure: " + self); } } else { throw new IllegalArgumentException("Unknown protocol: " + self); } if (self.isEmpty()) { self = "/"; } // Attempt to fix system differences with pathing try { File file = new File(self); if (file.exists()) { self = file.getCanonicalPath(); } } catch (IOException ex) { throw new IllegalArgumentException("Failed to resolve to a canonical path: " + self); } return self; } public static void main(String[] args) { System.out.println(findClassRootOfSelf()); } }