Export Guide - nicho92/MtgDesktopCompanion GitHub Wiki
This page documents the card import/export module used by MTG Desktop Companion to move decks, card search results, alerts, and stock entries between MTG Companion and external tools, marketplaces, clipboard formats, web endpoints, and files.
The module is implemented as the MTGCardsExport plugin family. Import/export plugins give MTG Companion a shared contract for:
- exporting a deck (
MTGDeck) to a destination file or external destination; - exporting stock rows (
List<MTGCardStock>) to a destination file or external destination; - importing a deck from a file or raw text payload;
- importing stock rows from a file or raw text payload;
- declaring whether the plugin imports, exports, or supports both directions;
- declaring the target category so UI menus can group providers consistently.
The plugin registry loads this family from org.magic.api.exports.impl under the /deckexports configuration area.
All import/export plugins inherit the aliases helper from AbstractMTGPlugin. That field is a shared PluginsAliasesProvider instance and should be the first place to put provider-specific translations that are likely to change outside the Java code.
PluginsAliasesProvider reads pluginAliases.json by plugin display name. By default it loads the online copy configured by MTGConstants.MTG_DESKTOP_ALIASES_URL; the bundled resource at src/main/resources/data/pluginsAliases.json is the local copy used when local aliases are enabled. In practice, this means import/export plugins can be adjusted for third-party format changes by updating alias data instead of rebuilding parser logic.
For card import/export providers, pluginAliases.json is intended to hold:
| Alias block | Direction | Used for | Helper methods |
|---|---|---|---|
regex |
Import/parsing | Provider line formats, CSV layouts, deck rows, stock rows, sideboard markers, and named variants such as default, deck, stock, or collection. |
aliases.getRegexFor(this, key) |
conditions |
Import and export | Conversion between EnumCondition values and provider condition labels. |
aliases.getConditionFor(...), aliases.getReversedConditionFor(...)
|
idSet |
Import and export | Conversion between MTG Companion set codes and provider-specific set ids. |
aliases.getSetIdFor(...), aliases.getReversedSetIdFor(...)
|
nameSet |
Import and export | Conversion between MTG Companion set names and provider-specific set names. |
aliases.getSetNameFor(...), aliases.getReversedSetNameFor(...)
|
Best practice for import/export providers is to keep regexes and enum/string conversions in pluginAliases.json whenever possible. Java code should call the helper methods from aliases and only keep structural parsing logic, object creation, and provider workflow code in the provider class. This keeps online marketplace/application naming changes, condition labels, and file-layout regex changes in configuration rather than hard-coded Java constants.
A typical entry looks like this:
{
"Provider Display Name": {
"regex": {
"default": "...",
"stock": "...",
"deck": "..."
},
"conditions": {
"NEAR_MINT": "Near Mint",
"LIGHTLY_PLAYED": "Lightly Played"
},
"idSet": {
"DOM": "DAR"
},
"nameSet": {
"The List": "Mystery Booster/The List"
}
}
}The top-level key must match getName() for the plugin because PluginsAliasesProvider looks up data with plug.getName().
Every card import/export provider implements MTGCardsExport. The contract exposes these capability groups:
| Capability | Methods | Notes |
|---|---|---|
| Deck file type | getDeckFileExtension() |
Defaults to the stock extension in AbstractCardExport unless overridden. |
| Stock file type | getStockFileExtension() |
Used by file choosers and export target names. |
| Deck export | exportDeck(MTGDeck deck, File dest) |
Writes or sends a deck. |
| Stock export | exportStock(List<MTGCardStock> stock, File f) |
Writes or sends stock entries. |
| Deck import |
importDeckFromFile(File f), importDeck(String content, String name)
|
Reads a deck from a file or content string. |
| Stock import |
importStockFromFile(File f), importStock(String content)
|
Reads stock entries from a file or content string. |
| Destination mode | needFile() |
true for file-backed providers, false for clipboard, online, or dialog-only flows. |
| Optional dialogs |
needDialogForDeck(MODS mod), needDialogForStock(MODS mod)
|
Allows providers to open custom import/export UI instead of a simple file chooser. |
| Category | getCategory() |
Groups menu entries as file, application, external format, online, manual, MTG Companion, or none. |
| Direction | getMods() |
Returns IMPORT, EXPORT, or BOTH. |
MTGCardsExport.MODS controls whether a provider appears in import menus, export menus, or both:
-
IMPORT— reads external content into MTG Companion. -
EXPORT— sends MTG Companion content to an external format or target. -
BOTH— supports both import and export.
AbstractCardExport returns BOTH by default, so export-only or import-only providers must override getMods().
Providers use EnumExportCategory to drive categorized UI menus:
| Category | Typical use |
|---|---|
FILE |
Generic local file formats. |
EXTERNAL_FILE_FORMAT |
Files shaped for websites or third-party tools. |
APPLICATION |
Application-specific formats such as MTGO, Forge, XMage, or Arena. |
ONLINE |
Providers that communicate with online services or import from URLs. |
MANUAL |
Clipboard, webcam, manual paste, or dialog-driven flows. |
MTGCOMPANION |
MTG Companion native interchange data. |
NONE |
Providers that should not be visually grouped as a normal destination. |
- The deck construction panel builds an import menu from enabled
MTGCardsExportplugins. - Providers are filtered to
IMPORTorBOTH. - If the provider needs a file and no custom dialog is required, a file chooser is opened with the provider deck extension.
- The selected file is processed by
DeckImportWorker, which callsimportDeckFromFilein the background. - When the worker finishes, the imported
MTGDeckreplaces the current deck in the construction panel.
-
JExportButtonbuilds an export menu from enabled providers. - Providers are filtered to
EXPORTorBOTH. - If the provider needs a file, a save dialog is created using the provider file extension.
- Deck and card-list exports run through
CardExportWorker, which callsexportDeck. - Alert exports are converted to a temporary deck-like list of one-copy cards before export.
-
JExportButton.initStockExportbuilds the same categorized export menu. - Providers are filtered to
EXPORTorBOTH. - File-backed providers receive a
stocks<extension>save target. -
StockExportWorkercallsexportStockin the background.
When the JSON HTTP server is enabled, the module also exposes lightweight routes:
| Route | Method | Behavior |
|---|---|---|
/cards/import/:provider |
POST |
Reads the request body and calls the named MTGCardsExport provider's importDeck(content, "webimport"). |
/deck/export/:provider/:idDeck |
GET |
Loads a deck by id, exports it with the named provider to a temporary file, then returns either file text or binary image content. |
The Swagger file documents /cards/import/{provider} as the endpoint for importing deck/card content through a provider.
Most providers extend AbstractCardExport, which provides defaults and adapters:
- plugin type is
EXPORT; -
getMods()defaults toBOTH; -
needFile()defaults totrue; - deck and stock extensions are shared unless the provider overrides
getDeckFileExtension(); - default category is
FILEfor file-backed providers, otherwiseNONE; - default dialog requirements are
false; - deck import/export can be adapted through stock import/export and vice versa;
- imported deck cards are converted to default
MTGCardStockrows with quantity, product, comment, and update flags.
Formatted file providers can extend AbstractFormattedFileCardExport to reuse common parsing behavior:
- split content into lines and optionally skip the first line;
- skip lines with provider-specific prefixes;
- match each line with a provider regex;
- resolve editions by set id or name aliases from
pluginAliases.json; - resolve cards by card id, name, or collector number;
- read regex patterns through
aliases.getRegexFor(this, key)instead of hard-coding format regexes; - expose a configurable
SEPARATORproperty.
- Create a class in
src/main/java/org/magic/api/exports/impl. - Extend
AbstractCardExportfor general providers orAbstractFormattedFileCardExportfor regex/line-based formats. - Implement at minimum:
-
getName(); -
getStockFileExtension(); -
exportDeckand/orexportStockif the provider exports; -
importDeck,importDeckFromFile,importStock, and/orimportStockFromFileif the provider imports.
-
- Override
getMods()for import-only or export-only providers. - Override
getCategory()when the defaultFILEcategory is not appropriate. - Override
needFile()for clipboard, online, or dialog-only flows. - Override
needDialogForDeckorneedDialogForStockwhen the provider needs custom user input. - Add or update the provider entry in
src/main/resources/data/pluginsAliases.jsonfor regex patterns, condition conversions, and set id/name aliases. - If the parser is line-based, define
skipFirstLine(),skipLinesStartWith(),getSeparator(), and consume regex/alias behavior throughAbstractFormattedFileCardExport. - Run the export provider test suite to exercise the plugin through both deck and stock paths.
Before shipping a provider or changing an existing one:
- The provider appears in the expected import/export menu only.
- The menu category matches the destination type.
- File chooser filters use the expected deck and stock extensions.
- Importers resolve cards through the enabled
MTGCardsProvider. - Regexes, condition labels, and set aliases are configured through
pluginAliases.jsoninstead of hard-coded in provider classes. - Exporters preserve quantities and sideboard/mainboard behavior when the format supports it.
- Non-file providers return
needFile() == falseand handle anulldestination safely. - Long-running import/export work reports observer progress where practical.
-
ExportsProviderTestsruns without new provider failures.
-
src/main/java/org/magic/api/interfaces/MTGCardsExport.java— plugin interface and mode enum. -
src/main/java/org/magic/api/interfaces/abstracts/AbstractMTGPlugin.java— base plugin class that exposes the sharedaliasesprovider. -
src/main/java/org/magic/api/interfaces/abstracts/AbstractCardExport.java— default adapters for deck and stock import/export. -
src/main/java/org/magic/api/interfaces/abstracts/extra/AbstractFormattedFileCardExport.java— helpers for formatted text/CSV-like providers. -
src/main/java/org/magic/api/beans/enums/EnumExportCategory.java— provider category enum. -
src/main/java/org/magic/api/exports/impl— provider implementations. -
src/main/java/org/magic/services/providers/PluginsAliasesProvider.java— loader and accessor for provider alias data. -
src/main/resources/data/pluginsAliases.json— bundled alias configuration for regexes, conditions, set ids, and set names. -
src/main/java/org/magic/gui/components/widgets/JExportButton.java— reusable desktop export menu button. -
src/main/java/org/magic/gui/components/deck/ConstructPanel.java— desktop deck import/export integration. -
src/main/java/org/magic/services/workers/CardExportWorker.java— background deck/card export worker. -
src/main/java/org/magic/services/workers/StockExportWorker.java— background stock export worker. -
src/main/java/org/magic/services/workers/DeckImportWorker.java— background deck import worker. -
src/main/java/org/magic/servers/impl/JSONHttpServer.java— JSON HTTP import/export routes. -
docs/swagger-jsonhttpserver.yaml— JSON HTTP API documentation. -
src/test/java/test/providers/ExportsProviderTests.java— provider smoke tests.