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.google.common.collect.Lists; 020import com.intellij.openapi.diagnostic.Logger; 021import com.intellij.openapi.project.Project; 022import com.intellij.openapi.util.Key; 023import com.intellij.openapi.util.io.FileUtil; 024import org.jetbrains.annotations.NotNull; 025import org.jetbrains.jet.lang.psi.JetFile; 026import org.jetbrains.k2js.utils.JetFileUtils; 027 028import java.io.File; 029import java.io.IOException; 030import java.io.InputStream; 031import java.util.ArrayList; 032import java.util.Collections; 033import java.util.Enumeration; 034import java.util.List; 035import java.util.zip.ZipEntry; 036import java.util.zip.ZipFile; 037 038public class LibrarySourcesConfig extends Config { 039 @NotNull 040 public static final Key<String> EXTERNAL_MODULE_NAME = new Key<String>("externalModule"); 041 @NotNull 042 public static final String UNKNOWN_EXTERNAL_MODULE_NAME = "<unknown>"; 043 044 @NotNull 045 private static final Logger LOG = Logger.getInstance("#org.jetbrains.k2js.config.LibrarySourcesConfig"); 046 047 @NotNull 048 private final List<String> files; 049 050 public LibrarySourcesConfig(@NotNull Project project, 051 @NotNull String moduleId, 052 @NotNull List<String> files, 053 @NotNull EcmaVersion ecmaVersion) { 054 super(project, moduleId, ecmaVersion); 055 this.files = files; 056 } 057 058 @NotNull 059 @Override 060 public List<JetFile> generateLibFiles() { 061 if (files.isEmpty()) { 062 return Collections.emptyList(); 063 } 064 065 List<JetFile> jetFiles = new ArrayList<JetFile>(); 066 String moduleName = UNKNOWN_EXTERNAL_MODULE_NAME; 067 for (String path : files) { 068 File file = new File(path); 069 if (!file.exists()) continue; // The path here may be copying from a library root configuration, i.e. may be absent 070 try { 071 String name = file.getName(); 072 if (path.charAt(0) == '@') { 073 moduleName = path.substring(1); 074 continue; 075 } 076 077 if (name.endsWith(".jar") || name.endsWith(".zip")) { 078 jetFiles.addAll(readZip(file)); 079 } 080 else { 081 JetFile psiFile = JetFileUtils.createPsiFile(path, FileUtil.loadFile(file), getProject()); 082 psiFile.putUserData(EXTERNAL_MODULE_NAME, moduleName); 083 jetFiles.add(psiFile); 084 } 085 } 086 catch (IOException e) { 087 LOG.error("While processing " + file, e); 088 } 089 } 090 091 return jetFiles; 092 } 093 094 private List<JetFile> readZip(File file) throws IOException { 095 ZipFile zipFile = new ZipFile(file); 096 try { 097 return traverseArchive(zipFile); 098 } 099 finally { 100 zipFile.close(); 101 } 102 } 103 104 @NotNull 105 private List<JetFile> traverseArchive(@NotNull ZipFile file) throws IOException { 106 List<JetFile> result = Lists.newArrayList(); 107 Enumeration<? extends ZipEntry> zipEntries = file.entries(); 108 while (zipEntries.hasMoreElements()) { 109 ZipEntry entry = zipEntries.nextElement(); 110 if (!entry.isDirectory() && entry.getName().endsWith(".kt")) { 111 InputStream stream = file.getInputStream(entry); 112 String text = FileUtil.loadTextAndClose(stream); 113 JetFile jetFile = JetFileUtils.createPsiFile(entry.getName(), text, getProject()); 114 jetFile.putUserData(EXTERNAL_MODULE_NAME, UNKNOWN_EXTERNAL_MODULE_NAME); 115 result.add(jetFile); 116 } 117 } 118 return result; 119 } 120}