/* * Copyright (C) 2021 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 lombok.spi; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.net.URI; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.tools.Diagnostic.Kind; import javax.tools.FileObject; import javax.tools.StandardLocation; class SpiProcessorPersistence { private final String name; private final String path; final Filer filer; private final Messager logger; SpiProcessorPersistence(String name, Filer filer, Messager logger) { this.name = name; this.logger = logger; this.path = SpiProcessor.getRootPathOfServiceFiles(); this.filer = filer; } static CharSequence readFilerResource(FileObject resource, Messager logger, String pathName) { try { // Eclipse can't handle getCharContent, so we must use a reader... return tryWithReader(resource); } catch (FileNotFoundException e) { return null; } catch (IOException e) { if ( e.getClass().getName().equals("org.eclipse.core.internal.resources.ResourceException") && e.getMessage() != null && e.getMessage().endsWith("does not exist.")) { return null; } logger.printMessage(Kind.ERROR, SpiProcessor.toErrorMsg(e, pathName)); return null; } catch (Exception other) { // otherwise, probably javac: Some versions don't support the `openReader` method. try { return resource.getCharContent(true); } catch (FileNotFoundException e) { return null; } catch (IOException e) { logger.printMessage(Kind.ERROR, SpiProcessor.toErrorMsg(e, pathName)); return null; } } } private static CharSequence tryWithReader(FileObject resource) throws IOException { StringBuilder sb = new StringBuilder(); Reader raw = resource.openReader(true); try { BufferedReader in = new BufferedReader(raw); for (String line = in.readLine(); line != null; line = in.readLine()) sb.append(line).append('\n'); return sb; } finally { if (raw != null) raw.close(); } } Collection<String> tryFind() { File dir = determineOutputLocation(); if (dir == null || !dir.isDirectory()) return Collections.emptyList(); List<String> out = new ArrayList<String>(); for (File p : dir.listFiles()) { if (!p.isFile()) continue; out.add(p.getName()); } return out; } private File determineOutputLocation() { FileObject resource; try { resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "META-INF", "locator.tmp"); } catch (FileNotFoundException e) { e.printStackTrace(); // Could happen return null; } catch (IOException e) { e.printStackTrace(); logger.printMessage(Kind.NOTE, "IOException while determining output location: " + e.getMessage()); return null; } catch (IllegalArgumentException e) { e.printStackTrace(); // Happens when the path is invalid. For instance absolute or relative to a path // not part of the class output folder. // // Due to a bug in javac for Linux, this also occurs when no output path is specified // for javac using the -d parameter. // See http://forums.sun.com/thread.jspa?threadID=5240999&tstart=45 // and http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6647996 return null; } URI uri = resource.toUri(); return new File(new File(uri).getParentFile(), "services"); } void write(String serviceName, String value) throws IOException { FileObject output = filer.createResource(StandardLocation.CLASS_OUTPUT, "", path + serviceName); Writer writer = output.openWriter(); writer.write("# Generated by " + name + "\n"); writer.write("# " + new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US).format(new Date()) + "\n"); writer.write(value); writer.close(); } }