Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package sootup.java.bytecode.inputlocation;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2018-2020 Andreas Dann, Christian Brüggemann and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.io.IOException;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import sootup.core.IdentifierFactory;
import sootup.core.frontend.AbstractClassSource;
import sootup.core.frontend.ClassProvider;
import sootup.core.frontend.ResolveException;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.types.ClassType;
import sootup.core.util.StreamUtils;
import sootup.core.views.View;
import sootup.java.bytecode.frontend.AsmJavaClassProvider;
import sootup.java.bytecode.frontend.AsmModuleSource;
import sootup.java.core.JavaModuleIdentifierFactory;
import sootup.java.core.JavaModuleInfo;
import sootup.java.core.JavaSootClass;
import sootup.java.core.ModuleInfoAnalysisInputLocation;
import sootup.java.core.signatures.ModulePackageName;
import sootup.java.core.signatures.ModuleSignature;
import sootup.java.core.types.JavaClassType;
/**
* Base class for {@link AnalysisInputLocation}s that can be located by a {@link Path} object.
*
* @author Andreas Dann created on 06.06.18
*/
public class JrtFileSystemAnalysisInputLocation implements ModuleInfoAnalysisInputLocation {
private static final FileSystem theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/"));
Map moduleInfoMap = new HashMap<>();
boolean isResolved = false;
@Override
@Nonnull
public Optional extends AbstractClassSource> getClassSource(
@Nonnull ClassType classType, @Nonnull View> view) {
JavaClassType klassType = (JavaClassType) classType;
ClassProvider classProvider = new AsmJavaClassProvider(view);
Path filepath =
theFileSystem.getPath(
klassType.getFullyQualifiedName().replace('.', '/')
+ "."
+ classProvider.getHandledFileType().getExtension());
// parse as module
if (klassType.getPackageName() instanceof ModulePackageName) {
ModulePackageName modulePackageSignature = (ModulePackageName) klassType.getPackageName();
final Path module =
theFileSystem.getPath(
"modules", modulePackageSignature.getModuleSignature().getModuleName());
Path foundClass = module.resolve(filepath);
if (Files.isRegularFile(foundClass)) {
return Optional.of(classProvider.createClassSource(this, foundClass, klassType));
} else {
return Optional.empty();
}
}
// module information does not exist in Signature -> search for class
final Path moduleRoot = theFileSystem.getPath("modules");
try (DirectoryStream stream = Files.newDirectoryStream(moduleRoot)) {
{
for (Path entry : stream) {
// check each module folder for the class
Path foundfile = entry.resolve(filepath);
if (Files.isRegularFile(foundfile)) {
return Optional.of(classProvider.createClassSource(this, foundfile, klassType));
}
}
}
} catch (IOException e) {
throw new ResolveException("Error loading a module", moduleRoot, e);
}
return Optional.empty();
}
/** Retreive CLassSources of a module specified by methodSignature */
@Override
@Nonnull
public Collection extends AbstractClassSource> getModulesClassSources(
@Nonnull ModuleSignature moduleSignature, @Nonnull View> view) {
return getClassSourcesInternal(moduleSignature, view.getIdentifierFactory(), view)
.collect(Collectors.toList());
}
@Nonnull
protected Stream> getClassSourcesInternal(
@Nonnull ModuleSignature moduleSignature,
@Nonnull IdentifierFactory identifierFactory,
@Nonnull View> view) {
ClassProvider classProvider = new AsmJavaClassProvider(view);
String moduleInfoFilename =
JavaModuleIdentifierFactory.MODULE_INFO_FILE
+ "."
+ classProvider.getHandledFileType().getExtension();
final Path archiveRoot = theFileSystem.getPath("modules", moduleSignature.getModuleName());
try {
return Files.walk(archiveRoot)
.filter(
filePath ->
!Files.isDirectory(filePath)
&& filePath
.toString()
.endsWith(classProvider.getHandledFileType().getExtension())
&& !filePath.toString().endsWith(moduleInfoFilename))
.flatMap(
p -> {
return StreamUtils.optionalToStream(
Optional.of(
classProvider.createClassSource(
this,
p,
this.fromPath(
p.subpath(2, p.getNameCount()),
p.subpath(1, 2),
identifierFactory))));
});
} catch (IOException e) {
throw new ResolveException("Error loading module " + moduleSignature, archiveRoot, e);
}
}
@Override
public @Nonnull Collection extends AbstractClassSource> getClassSources(
@Nonnull View> view) {
Collection moduleSignatures = discoverModules();
return moduleSignatures.stream()
.flatMap(sig -> getClassSourcesInternal(sig, view.getIdentifierFactory(), view))
.collect(Collectors.toList());
}
/**
* Discover and return all modules contained in the jrt filesystem.
*
* @return Collection of found module names.
*/
@Nonnull
public Collection discoverModules() {
if (!isResolved) {
final Path moduleRoot = theFileSystem.getPath("modules");
final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class";
try (DirectoryStream stream = Files.newDirectoryStream(moduleRoot)) {
{
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
ModuleSignature moduleSignature =
JavaModuleIdentifierFactory.getModuleSignature(entry.subpath(1, 2).toString());
Path moduleInfo = entry.resolve(moduleInfoFilename);
if (Files.exists(moduleInfo)) {
moduleInfoMap.put(moduleSignature, new AsmModuleSource(moduleInfo));
} else {
moduleInfoMap.put(
moduleSignature, JavaModuleInfo.createAutomaticModuleInfo(moduleSignature));
}
}
}
}
} catch (IOException e) {
throw new ResolveException("Error while discovering modules", moduleRoot, e);
}
isResolved = true;
}
return moduleInfoMap.keySet();
}
@Nonnull
private JavaClassType fromPath(
final Path filename, final Path moduleDir, final IdentifierFactory identifierFactory) {
// else use the module system and create fully class signature
// we do not have a base directory here, the moduleDir is actually not a directory
JavaClassType sig = (JavaClassType) identifierFactory.fromPath(Paths.get(""), filename);
if (identifierFactory instanceof JavaModuleIdentifierFactory) {
return ((JavaModuleIdentifierFactory) identifierFactory)
.getClassType(
sig.getClassName(), sig.getPackageName().getPackageName(), moduleDir.toString());
}
// if we are using the normal signature factory, then trim the module from the path
return sig;
}
@Nonnull
@Override
public Optional getModuleInfo(ModuleSignature sig, View> view) {
if (!isResolved) {
discoverModules();
}
return Optional.ofNullable(moduleInfoMap.get(sig));
}
@Nonnull
@Override
public Set getModules(View> view) {
if (!isResolved) {
discoverModules();
}
return Collections.unmodifiableSet(moduleInfoMap.keySet());
}
@Override
public boolean equals(Object o) {
return o instanceof JrtFileSystemAnalysisInputLocation;
}
@Override
public int hashCode() {
return 31;
}
}