Skip to content

Commit

Permalink
Refactor WorkspaceProcessingService to allow registering custom proce…
Browse files Browse the repository at this point in the history
…ssors
  • Loading branch information
Col-E committed Dec 8, 2024
1 parent fab9408 commit 5484258
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
Expand Down Expand Up @@ -66,6 +65,28 @@ public TransformationManager(@Nonnull Map<Class<? extends JvmClassTransformer>,
this.config = new TransformationManagerConfig();
}

/**
* @param transformerClass
* Class of transformer to register.
* @param transformerSupplier
* Supplier of transformer instances.
* @param <T>
* Transformer type.
*/
public <T extends JvmClassTransformer> void registerJvmClassTransformer(@Nonnull Class<T> transformerClass, @Nonnull Supplier<T> transformerSupplier) {
jvmTransformerSuppliers.put(Unchecked.cast(transformerClass), Unchecked.cast(transformerSupplier));
}

/**
* @param transformerClass
* Class of transformer to unregister.
* @param <T>
* Transformer type.
*/
public <T extends JvmClassTransformer> void unregisterJvmClassTransformer(@Nonnull Class<T> transformerClass) {
jvmTransformerSuppliers.remove(Unchecked.cast(transformerClass));
}

@Nonnull
@SuppressWarnings("unchecked")
public <T extends JvmClassTransformer> T newJvmTransformer(@Nonnull Class<T> type) throws TransformationException {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package software.coley.recaf.services.workspace;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import software.coley.recaf.config.BasicConfigContainer;
import software.coley.recaf.config.ConfigGroups;
import software.coley.recaf.services.ServiceConfig;

/**
* Config for {@link WorkspaceProcessingService}.
*
* @author Matt Coley
*/
@ApplicationScoped
public class WorkspaceProcessingConfig extends BasicConfigContainer implements ServiceConfig {
@Inject
public WorkspaceProcessingConfig() {
super(ConfigGroups.SERVICE_TRANSFORM, WorkspaceProcessingService.SERVICE_ID + CONFIG_SUFFIX);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package software.coley.recaf.services.workspace;

import jakarta.annotation.Nonnull;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.inject.Inject;
import org.slf4j.Logger;
import software.coley.collections.Unchecked;
import software.coley.recaf.Bootstrap;
import software.coley.recaf.analytics.logging.Logging;
import software.coley.recaf.cdi.EagerInitialization;
import software.coley.recaf.services.Service;
import software.coley.recaf.workspace.model.Workspace;

import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
* Applies all discovered {@link WorkspaceProcessor} instances to {@link Workspace} instances upon loading them via
* {@link WorkspaceManager#setCurrent(Workspace)}.
*
* @author Matt Coley
* @see WorkspaceProcessor Processor type to implement.
*/
@EagerInitialization
@ApplicationScoped
public class WorkspaceProcessingService implements Service {
public static final String SERVICE_ID = "workspace-processing";
private static final Logger logger = Logging.get(WorkspaceProcessingService.class);
private final Map<Class<? extends WorkspaceProcessor>, Supplier<WorkspaceProcessor>> processorSuppliers = new IdentityHashMap<>();
private final WorkspaceProcessingConfig config;

/**
* @param workspaceManager
* Manager to facilitate listening to new opened workspaces.
* @param config
* Service config.
* @param processors
* Discovered processors to apply.
*/
@Inject
public WorkspaceProcessingService(@Nonnull WorkspaceManager workspaceManager,
@Nonnull WorkspaceProcessingConfig config,
@Nonnull Instance<WorkspaceProcessor> processors) {
this.config = config;
for (Instance.Handle<WorkspaceProcessor> handle : processors.handles()) {
Bean<WorkspaceProcessor> bean = handle.getBean();
Class<? extends WorkspaceProcessor> processorClass = Unchecked.cast(bean.getBeanClass());
processorSuppliers.put(processorClass, () -> {
// Even though our processors may be @Dependent scoped, we need to do a new lookup each time we want
// a new instance to get our desired scope behavior. If we re-use the instance handle that is injected
// here then even @Dependent scoped beans will yield the same instance again and again.
return Bootstrap.get().get(processorClass);
});
}

// Apply processors when new workspace is opened
workspaceManager.addWorkspaceOpenListener(this::processWorkspace);
}

/**
* @param processorClass
* Class of processor to register.
* @param processorSupplier
* Supplier of processor instances.
* @param <T>
* Processor type.
*/
public <T extends WorkspaceProcessor> void register(@Nonnull Class<T> processorClass, @Nonnull Supplier<T> processorSupplier) {
processorSuppliers.put(Unchecked.cast(processorClass), Unchecked.cast(processorSupplier));
}

/**
* @param processorClass
* Class of processor to unregister.
* @param <T>
* Processor type.
*/
public <T extends WorkspaceProcessor> void unregister(@Nonnull Class<T> processorClass) {
processorSuppliers.remove(Unchecked.cast(processorClass));
}

/**
* Applies all processors to the given workspace.
*
* @param workspace
* Workspace to process.
*/
public void processWorkspace(@Nonnull Workspace workspace) {
for (Supplier<WorkspaceProcessor> processorSupplier : processorSuppliers.values()) {
WorkspaceProcessor processor = processorSupplier.get();

logger.trace("Applying workspace processor: {}", processor.name());
processor.processWorkspace(workspace);
}
}

@Nonnull
@Override
public String getServiceId() {
return SERVICE_ID;
}

@Nonnull
@Override
public WorkspaceProcessingConfig getServiceConfig() {
return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
import software.coley.recaf.workspace.model.Workspace;

/**
* Subtype of {@link WorkspaceOpenListener} for use in {@link WorkspaceProcessing}.
* Generic processor for use in {@link WorkspaceProcessingService}.
*
* @author Matt Coley
* @see WorkspaceProcessing Manages calling implementations of this type.
* @see WorkspaceProcessingService Manages calling implementations of this type.
*/
public interface WorkspaceProcessor {
/**
* Called when {@link WorkspaceManager#setCurrent(Workspace)} passes.
*
* @param workspace
* New workspace assigned.
* Workspace to process.
*/
void onWorkspaceOpened(@Nonnull Workspace workspace);
void processWorkspace(@Nonnull Workspace workspace);

/**
* @return Post processing task name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public ThrowablePropertyAssigningProcessor(@Nonnull InheritanceGraphService grap
}

@Override
public void onWorkspaceOpened(@Nonnull Workspace workspace) {
public void processWorkspace(@Nonnull Workspace workspace) {
inheritanceGraph.getVertex(THROWABLE).allChildren().forEach(vertex -> {
ClassInfo classInfo = vertex.getValue();
ThrowableProperty.set(classInfo);
Expand Down

0 comments on commit 5484258

Please sign in to comment.