001/* 002 * Copyright 2010-2013 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.jetbrains.k2js.config; 018 019import com.intellij.openapi.project.Project; 020import com.intellij.openapi.util.io.FileUtil; 021import org.jetbrains.annotations.NotNull; 022import org.jetbrains.jet.lang.psi.JetFile; 023import org.jetbrains.k2js.utils.JetFileUtils; 024 025import java.io.BufferedReader; 026import java.io.IOException; 027import java.io.InputStream; 028import java.io.InputStreamReader; 029import java.net.URL; 030import java.util.*; 031 032/** 033 * A helper class to discover a META-INF/services file on the classpath and load the files referenced inside it 034 */ 035public final class MetaInfServices { 036 private MetaInfServices() { 037 } 038 039 public static List<JetFile> loadServicesFiles(@NotNull String metaInfServicesFile, @NotNull Project project) { 040 List<JetFile> libFiles = new ArrayList<JetFile>(); 041 Set<URL> urlsLoaded = new HashSet<URL>(); 042 try { 043 Enumeration<URL> resources = MetaInfServices.class.getClassLoader().getResources(metaInfServicesFile); 044 loadLibFiles(resources, urlsLoaded, libFiles, project); 045 resources = Thread.currentThread().getContextClassLoader().getResources(metaInfServicesFile); 046 loadLibFiles(resources, urlsLoaded, libFiles, project); 047 } 048 catch (IOException e) { 049 throw new IllegalStateException(e); 050 } 051 return libFiles; 052 } 053 054 private static void loadLibFiles(@NotNull Enumeration<URL> resources, 055 @NotNull Set<URL> urlsLoaded, 056 @NotNull List<JetFile> libFiles, 057 @NotNull Project project) 058 throws IOException { 059 while (resources.hasMoreElements()) { 060 URL url = resources.nextElement(); 061 if (url != null) { 062 if (urlsLoaded.add(url)) { 063 BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); 064 try { 065 while (true) { 066 String line = reader.readLine(); 067 if (line == null) { 068 break; 069 } 070 else { 071 line = line.trim(); 072 if (line.length() == 0 || line.startsWith("#")) continue; 073 // lets try to discover the file 074 InputStream stream = loadClasspathResource(line); 075 if (stream != null) { 076 String text = FileUtil.loadTextAndClose(stream); 077 JetFile file = JetFileUtils.createPsiFile(line, text, project); 078 libFiles.add(file); 079 } 080 } 081 } 082 } 083 finally { 084 reader.close(); 085 } 086 } 087 } 088 } 089 } 090 091 /** 092 * Tries to load the given resource name on the classpath 093 */ 094 public static InputStream loadClasspathResource(String resourceName) { 095 InputStream answer = ClassPathLibraryDefintionsConfig.class.getClassLoader().getResourceAsStream(resourceName); 096 if (answer == null) { 097 answer = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName); 098 } 099 return answer; 100 } 101}