package org.osmorc.facet;
import com.intellij.facet.FacetType;
import com.intellij.framework.detection.FacetBasedFrameworkDetector;
import com.intellij.framework.detection.FileContentPattern;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PatternCondition;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.FileContent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.lang.manifest.ManifestFileTypeFactory;
import org.jetbrains.osgi.jps.model.ManifestGenerationMode;
import org.osgi.framework.Constants;
import java.util.*;
/**
* @author nik
*/
public class OsmorcFrameworkDetector extends FacetBasedFrameworkDetector<OsmorcFacet, OsmorcFacetConfiguration> {
private final Logger logger = Logger.getInstance("#org.osmorc.facet.OsmorcFrameworkDetector");
private final String[] DETECTION_HEADERS = {Constants.BUNDLE_SYMBOLICNAME};
public OsmorcFrameworkDetector() {
super("osmorc");
}
@NotNull
@Override
public FacetType<OsmorcFacet, OsmorcFacetConfiguration> getFacetType() {
return OsmorcFacetType.getInstance();
}
@Override
protected OsmorcFacetConfiguration createConfiguration(Collection<VirtualFile> files) {
OsmorcFacetConfiguration osmorcFacetConfiguration = getFacetType().createDefaultConfiguration();
osmorcFacetConfiguration.setManifestGenerationMode(ManifestGenerationMode.Manually);
osmorcFacetConfiguration.setManifestLocation(ContainerUtil.getFirstItem(files).getPath());
osmorcFacetConfiguration.setUseProjectDefaultManifestFileLocation(false);
return osmorcFacetConfiguration;
}
@Override
public void setupFacet(@NotNull OsmorcFacet facet, ModifiableRootModel model) {
VirtualFile[] contentRoots = model.getContentRoots();
OsmorcFacetConfiguration osmorcFacetConfiguration = facet.getConfiguration();
VirtualFile manifestFile = LocalFileSystem.getInstance().findFileByPath(osmorcFacetConfiguration.getManifestLocation());
if (manifestFile != null) {
for (VirtualFile contentRoot : contentRoots) {
if (VfsUtilCore.isAncestor(contentRoot, manifestFile, false)) {
// IDEADEV-40357
osmorcFacetConfiguration.setManifestLocation(VfsUtilCore.getRelativePath(manifestFile, contentRoot, '/'));
break;
}
}
}
else {
osmorcFacetConfiguration.setManifestLocation("");
osmorcFacetConfiguration.setUseProjectDefaultManifestFileLocation(true);
}
String manifestFileName = osmorcFacetConfiguration.getManifestLocation();
if (manifestFileName.endsWith("template.mf")) { // this is a bundlor manifest template, so make the facet do bundlor
osmorcFacetConfiguration.setManifestLocation("");
osmorcFacetConfiguration.setBundlorFileLocation(manifestFileName);
osmorcFacetConfiguration.setManifestGenerationMode(ManifestGenerationMode.Bundlor);
}
}
@NotNull
@Override
public ElementPattern<FileContent> createSuitableFilePattern() {
return FileContentPattern.fileContent().with(new PatternCondition<FileContent>("osmorc manifest file") {
@Override
public boolean accepts(@NotNull FileContent content, ProcessingContext context) {
return isSuitableFile(content.getContentAsText());
}
});
}
@NotNull
@Override
public FileType getFileType() {
return ManifestFileTypeFactory.MANIFEST;
}
private boolean isSuitableFile(CharSequence fileContent) {
List<String> headersToDetect = new ArrayList<>(Arrays.asList(DETECTION_HEADERS));
StringTokenizer linesTokenizer = new StringTokenizer(fileContent.toString(), "\r\n");
while (linesTokenizer.hasMoreTokens()) {
String line = linesTokenizer.nextToken();
for (Iterator<String> iterator = headersToDetect.iterator(); iterator.hasNext(); ) {
String headerToDetect = iterator.next();
if (line.startsWith(headerToDetect)) {
iterator.remove();
break;
}
}
}
return headersToDetect.size() == 0;
}
}