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