package com.intellij.lang.javascript.flex.projectStructure.detection;
import com.intellij.ide.util.importProject.ModuleDescriptor;
import com.intellij.ide.util.importProject.ModuleInsight;
import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot;
import com.intellij.ide.util.projectWizard.importSources.DetectedSourceRoot;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.javascript.JSTokenTypes;
import com.intellij.lang.javascript.JavaScriptSupportLoader;
import com.intellij.lang.javascript.flex.FlexModuleType;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
import com.intellij.util.xml.NanoXmlUtil;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.util.Collection;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class FlexModuleInsight extends ModuleInsight {
public FlexModuleInsight(@Nullable final ProgressIndicator progress,
Set<String> existingModuleNames,
Set<String> existingProjectLibraryNames) {
super(progress, existingModuleNames, existingProjectLibraryNames);
}
protected ModuleDescriptor createModuleDescriptor(final File moduleContentRoot, final Collection<DetectedSourceRoot> sourceRoots) {
return new ModuleDescriptor(moduleContentRoot, FlexModuleType.getInstance(), sourceRoots);
}
protected boolean isSourceFile(final File file) {
// TODO we need to scan import statements in MXML files as well
return FlexProjectStructureDetector.isActionScriptFile(file);
}
protected void scanSourceFileForImportedPackages(final CharSequence chars, final Consumer<String> result) {
Lexer lexer = LanguageParserDefinitions.INSTANCE.forLanguage(JavaScriptSupportLoader.ECMA_SCRIPT_L4).createLexer(null);
lexer.start(chars);
if (FlexProjectStructureDetector.readPackageName(chars, lexer) == null) {
return;
}
while (true) {
while (lexer.getTokenType() != null && lexer.getTokenType() != JSTokenTypes.IMPORT_KEYWORD) {
lexer.advance();
}
if (lexer.getTokenType() == null) {
break;
}
lexer.advance();
FlexProjectStructureDetector.skipWhiteSpaceAndComments(lexer);
String packageName = FlexProjectStructureDetector.readQualifiedName(chars, lexer, true);
if (packageName != null) {
String s = packageName.endsWith(".*") ? StringUtil.trimEnd(packageName, ".*") : StringUtil.getPackageName(packageName);
if (!s.isEmpty()) {
result.consume(s);
}
}
}
}
protected boolean isLibraryFile(final String fileName) {
return fileName.toLowerCase().endsWith(".swc");
}
protected void scanLibraryForDeclaredPackages(final File file, final Consumer<String> result) throws IOException {
FileInputStream in = null;
try {
in = new FileInputStream(file);
ZipInputStream zip = new ZipInputStream(in);
ZipEntry e;
while ((e = zip.getNextEntry()) != null) {
if (!e.isDirectory() && "catalog.xml".equals(e.getName())) {
InputStreamReader reader = new InputStreamReader(zip, "UTF-8");
NanoXmlUtil.parse(reader, new NanoXmlUtil.IXMLBuilderAdapter() {
private boolean processingDef;
@Override
public void startElement(String name, String nsPrefix, String nsURI, String systemID, int lineNr) throws Exception {
if (name.equals("def")) {
processingDef = true;
}
}
@Override
public void endElement(String name, String nsPrefix, String nsURI) throws Exception {
if (name.equals("def")) {
processingDef = false;
}
}
@Override
public void addAttribute(String name, String nsPrefix, String nsURI, String value, String type) throws Exception {
if (processingDef && name.equals("id")) {
String fqn = value.replace(':', '.');
String packageName = StringUtil.getPackageName(fqn);
if (!packageName.isEmpty()) {
result.consume(packageName);
}
}
}
});
}
}
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException ignored) {
}
}
}
}
public boolean isApplicableRoot(final DetectedProjectRoot root) {
return root instanceof FlexModuleSourceRoot;
}
}