/*
* Nocturne
* Copyright (c) 2015-2016, Lapis <https://github.com/LapisBlue>
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package blue.lapis.nocturne.jar.model;
import blue.lapis.nocturne.jar.model.hierarchy.Hierarchy;
import blue.lapis.nocturne.jar.model.hierarchy.HierarchyNode;
import blue.lapis.nocturne.util.Constants;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Represents a set of {@link JarClassEntry JarClassEntries} loaded from a JAR
* file.
*/
public class ClassSet {
private final String name;
private final Map<String, JarClassEntry> classMap = new HashMap<>();
private final BiMap<String, String> names = HashBiMap.create();
/**
* Constructs a new {@link ClassSet} from the given {@link JarClassEntry}
* {@link Set}.
*
* @param classes The {@link JarClassEntry JarClassEntries} to populate the
* new {@link ClassSet} with
*/
public ClassSet(String name, Set<JarClassEntry> classes) {
this.name = name;
classes.forEach(cl -> {
classMap.put(cl.getName(), cl);
getCurrentNames().put(cl.getName(), cl.getName());
});
}
/**
* Returns the name of this {@link ClassSet}.
*
* @return The name of this {@link ClassSet}
*/
public String getName() {
return name;
}
/**
* Returns an {@link ImmutableSet} of all classes contained by this
* this {@link ClassSet}.
*
* @return An {@link ImmutableSet} of all classes contained by this
* this {@link ClassSet}
*/
public ImmutableSet<JarClassEntry> getClasses() {
return ImmutableSet.copyOf(classMap.values());
}
/**
* Returns an {@link ImmutableSet} of all obfuscated classes contained by
* this {@link ClassSet}.
*
* @return An {@link ImmutableSet} of all obfuscated classes contained by
* this {@link ClassSet}
*/
public ImmutableSet<JarClassEntry> getObfuscatedClasses() {
return ImmutableSet.copyOf(getClasses().stream().filter(c -> !c.isDeobfuscated()).collect(Collectors.toSet()));
}
/**
* Returns an {@link ImmutableSet} of all deobfuscated classes contained by
* this {@link ClassSet}.
*
* @return An {@link ImmutableSet} of all deobfuscated classes contained by
* this {@link ClassSet}
*/
public ImmutableSet<JarClassEntry> getDeobfuscatedClasses() {
return ImmutableSet.copyOf(getClasses().stream().filter(JarClassEntry::isDeobfuscated)
.collect(Collectors.toSet()));
}
/**
* Returns the {@link JarClassEntry} for the given FQ name, if it exists.
*
* @return The {@link JarClassEntry} for the given FQ name, or
* {@link Optional#empty()} if it does not exist in this
* {@link ClassSet}
*/
public Optional<JarClassEntry> getClass(String name) {
return classMap.containsKey(name) ? Optional.of(classMap.get(name)) : Optional.empty();
}
/**
* Returns a {@link HierarchyNode} representing the structure of
* obfuscated classes contained by this {@link ClassSet}.
*
* @return A {@link HierarchyNode} representing the structure of
* obfuscated classes contained by this {@link ClassSet}
*/
public Hierarchy getObfuscatedHierarchy() {
return generateHierarchy(getObfuscatedClasses(), false);
}
/**
* Returns a {@link HierarchyNode} representing the structure of
* deobfuscated classes contained by this {@link ClassSet}.
*
* @return A {@link HierarchyNode} representing the structure of
* deobfuscated classes contained by this {@link ClassSet}
*/
public Hierarchy getDeobfuscatedHierarchy() {
return generateHierarchy(getDeobfuscatedClasses(), true);
}
/**
* Generates a {@link HierarchyNode} from the given {@link JarClassEntry}
* {@link Set}.
*
* @param entrySet The {@link JarClassEntry} {@link Set} to generate the
* {@link HierarchyNode} from
* @return The generated {@link HierarchyNode}
*/
private Hierarchy generateHierarchy(Set<JarClassEntry> entrySet, boolean deobfuscate) {
return Hierarchy.fromSet(entrySet.stream()
.filter(e -> !e.getName().contains(Constants.INNER_CLASS_SEPARATOR_CHAR + ""))
//.map(deobfuscate ? JarClassEntry::getDeobfuscatedName : JarClassEntry::getName)
.collect(Collectors.toSet()), deobfuscate);
}
public BiMap<String, String> getCurrentNames() {
return names;
}
}