The workspace
A workspace is the outline of one or more input files.
Legend
The primary resource is the input that is targeted for editing. If you drag and drop a single JAR file into Recaf, then this will represent that JAR file. The representation is broken down into pieces...
The JVM class bundle contains all the
.class
files in the input that are not treated specially by the JVM.JAR files allow you to have multiple versions of the same class for different JVM versions via "Multi-release JAR". This is a map of JVM version numbers to bundles of classes associated with that specific version.
Android's APK files may contain multiple containers of classes known as DEX files. This is a mapping of each DEX file to the classes contained within it.
The file bundle contains all other regular files that are not ZIP archives.
ZIP archives are represented as embedded resources, allowing a ZIP in a ZIP, or JAR in a JAR, to be navigable within Recaf.
Workspaces can have multiple inputs. These additional inputs can be used to enhance performance of some services such as inheritance graphing, recompilation, and SSVM virtualization just to name a few. These supporting resources are not intended to be editable and are just there to "support" services as described before.
Recaf adds a few of its own supporting resources, but manages them separately from the supporting resources list.
The runtime resource allows Recaf to access classes in the current JVM process like
java.lang.String
.The android resource allows Recaf to access classes in the Android runtime. It is automatically loaded when a resource with DEX files is detected.
Creating workspaces
To create a Workspace
instance you will almost always be using the BasicWorkspace
implementation. You can pass along either:
A single
WorkspaceResource
for the primary resource.A single
WorkspaceResource
for the primary resource, plusCollection<WorkspaceResource>
for the supporting resources.
To create a WorkspaceResource
you can use the ResourceImporter
service, which allows you to read content from a variety of inputs.
Loading workspaces
There are multiple ways to load workspaces internally. Depending on your intent you'll want to do it differently.
For loading from Path
values in a UI context, use PathLoadingManager
. It will handle loading the content from the path in a background thread, and gives you a simple consumer type to handle IO problems.
Otherwise, you can use WorkspaceManager
directly to call setCurrent(Workspace)
.
Exporting workspaces
You can create an instance of WorkspaceExportOptions
and configure them to suite your needs. The options allow you to change:
The compression scheme of contents.
MATCH_ORIGINAL
which will only compress items if they were originally compressed when read.SMART
which will only compress items if compression yields a smaller output than a non-compressed item. Very small files may become larger with compression due to the overhead of the compression scheme's dictionary.ALWAYS
which always compresses items.NEVER
which never compresses items.
The output type, being a file or directory.
The path to write to.
The option to bundle contents of supporting resources into the exported output.
The option to create ZIP file directory entries, if the output type is
FILE
. This creates empty entries in the output of ZIP/JAR files detailing directory paths. Some tools may use this data, but its not required for most circumstances.
The configured options instance can be re-used to export contents with the same configuration multiple times. To export a workspace do options.create()
to create a WorkspaceExporter
which then allows you to pass a Workspace
instance.
Listeners
The WorkspaceManager
allows you to register listeners for multiple workspace events.
WorkspaceOpenListener
: When a new workspace is opened within the manager.WorkspaceCloseListener
: When a prior workspace is closed within the manager.WorkspaceModificationListener
: When the active workspace's model is changed (Supporting resource added/removed)
When creating services and CDI enabled classes, you can annotate the class with @AutoRegisterWorkspaceListeners
to automatically register and unregister the class based on what is necessary for the CDI scope.
Accessing classes/files in the workspace
Classes and files reside within the WorkspaceResource
items in a Workspace
. You can access the resources directly like so:
As described in the workspace model above, resources have multiple "bundles" that contain content. The groups exist to facilitate modeling a variety of potential input types that Recaf supports. Bundles that represent classes share a common type ClassBundle
and then are broken down further into JvmClassBundle
and AndroidClassBundle
where relevant. Bundles that represent files are only ever FileBundle
.
These bundles are Map<String, T>
and Iterable<T>
where T
is the content type.
Finding specific classes/files in the workspace
The Workspace
interface defines some find
operations allowing for simple name look-ups of classes and files.
Last updated