Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove BCheckManager and move state to StorefrontModel. #38

Merged
merged 2 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions src/main/java/Extension.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import bcheck.BCheckFactory;
import bcheck.BCheckManager;
import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.persistence.Persistence;
Expand All @@ -13,10 +12,18 @@
import network.RequestSender;
import settings.controller.SettingsController;
import ui.clipboard.ClipboardManager;
import ui.controller.StoreController;
import ui.icons.IconFactory;
import ui.model.DefaultStorefrontModel;
import ui.model.LateInitializationStorefrontModel;
import ui.model.StorefrontModel;
import ui.view.BCheckStore;
import ui.view.pane.settings.Settings;
import ui.view.pane.storefront.Storefront;
import utils.CloseablePooledExecutor;

import java.util.concurrent.atomic.AtomicReference;

public class Extension implements BurpExtension {
private static final String TAB_TITLE = "BCheck Helper";

Expand All @@ -35,16 +42,35 @@ public void initialize(MontoyaApi api) {
BCheckFetcher onlineBCheckFetcher = new BCheckFetcher(bCheckFactory, gitHubClient, tempFileCreator, zipExtractor, bCheckFileFinder, settingsController.gitHubSettings());
CloseablePooledExecutor executor = new CloseablePooledExecutor();

BCheckStore bcheckStore = new BCheckStore(
new BCheckManager(onlineBCheckFetcher),
new ClipboardManager(),
new FileSystem(logger),
settingsController,
IconFactory iconFactory = new IconFactory(api.userInterface());
ClipboardManager clipboardManager = new ClipboardManager();
FileSystem fileSystem = new FileSystem(logger);

AtomicReference<StorefrontModel> modelReference = new AtomicReference<>();
StorefrontModel lateInitializationStorefrontModel = new LateInitializationStorefrontModel(modelReference::get);
StoreController storeController = new StoreController(
lateInitializationStorefrontModel,
onlineBCheckFetcher,
clipboardManager,
fileSystem
);

StorefrontModel storefrontModel = new DefaultStorefrontModel(storeController);
modelReference.set(storefrontModel);

Settings settings = new Settings(settingsController);

Storefront storefront = new Storefront(
storeController,
storefrontModel,
settingsController.defaultSaveLocationSettings(),
executor,
new IconFactory(api.userInterface()),
iconFactory,
logger
);

BCheckStore bcheckStore = new BCheckStore(settings, storefront);

api.userInterface().registerSuiteTab(TAB_TITLE, bcheckStore);
api.extension().registerUnloadingHandler(executor::close);
}
Expand Down
61 changes: 0 additions & 61 deletions src/main/java/bcheck/BCheckManager.java

This file was deleted.

34 changes: 19 additions & 15 deletions src/main/java/ui/controller/StoreController.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,50 @@
package ui.controller;

import bcheck.BCheck;
import bcheck.BCheckManager;
import fetcher.BCheckFetcher;
import file.system.FileSystem;
import ui.clipboard.ClipboardManager;
import ui.model.StorefrontModel;

import java.nio.file.Path;
import java.util.List;
import java.util.function.Predicate;

import static java.util.Collections.emptyList;
import static ui.model.State.ERROR;

public class StoreController {
private final BCheckManager bCheckManager;
private final StorefrontModel model;
private final BCheckFetcher onlineBCheckFetcher;
private final ClipboardManager clipboardManager;
private final FileSystem fileSystem;

public StoreController(
BCheckManager bCheckManager,
StorefrontModel model,
BCheckFetcher bCheckFetcher,
ClipboardManager clipboardManager,
FileSystem fileSystem
) {
this.bCheckManager = bCheckManager;
this.model = model;
this.onlineBCheckFetcher = bCheckFetcher;
this.clipboardManager = clipboardManager;
this.fileSystem = fileSystem;
}

public String status() {
return switch (bCheckManager.state()) {
case START -> "Loading";
case INITIAL_LOAD -> "Loaded %d BCheck scripts".formatted(bCheckManager.numberOfBChecks());
case REFRESH -> "Refreshed";
case ERROR -> "Error contacting GitHub repository";
};
}

public void loadData() {
bCheckManager.loadData();
model.setStatus("");

try {
model.updateModel(onlineBCheckFetcher.fetchAllBChecks(), model.state().nextState());
} catch (Exception e) {
model.updateModel(emptyList(), ERROR);
}
}

public List<BCheck> findMatchingBChecks(String searchText) {
Predicate<BCheck> filter = searchText.isBlank() ? bCheck -> true : new BCheckFilterPredicate(searchText);

return bCheckManager.availableBChecks().stream().filter(filter).toList();
return model.getAvailableBChecks().stream().filter(filter).toList();
}

public void copyBCheck(BCheck bCheck) {
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/ui/controller/TablePanelController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ui.controller;

public interface TablePanelController {
void loadData();

class DefaultTablePanelController implements TablePanelController {
private final StoreController storeController;

public DefaultTablePanelController(StoreController storeController) {
this.storeController = storeController;
}

@Override
public void loadData() {
storeController.loadData();
}
}
}
100 changes: 100 additions & 0 deletions src/main/java/ui/model/DefaultStorefrontModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package ui.model;

import bcheck.BCheck;
import ui.controller.StoreController;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import static java.util.Collections.synchronizedList;
import static java.util.Comparator.comparing;

public class DefaultStorefrontModel implements StorefrontModel {
private final StoreController controller;
private final List<BCheck> allAvailableBChecks;
private final PropertyChangeSupport propertyChangeSupport;

private State state;
private String searchFilter;
private String status;
private BCheck selectedBCheck;

public DefaultStorefrontModel(StoreController controller) {
this.controller = controller;

this.state = State.START;
this.allAvailableBChecks = synchronizedList(new ArrayList<>());
this.propertyChangeSupport = new PropertyChangeSupport(this);
}

@Override
public void setSelectedBCheck(BCheck selectedBCheck) {
BCheck oldselectedBCheck = this.selectedBCheck;
this.selectedBCheck = selectedBCheck;
propertyChangeSupport.firePropertyChange(SELECTED_BCHECK_CHANGED, oldselectedBCheck, selectedBCheck);
}

@Override
public BCheck getSelectedBCheck() {
return selectedBCheck;
}

@Override
public void setSearchFilter(String searchFilter) {
String oldSearchFilter = this.searchFilter;
this.searchFilter = searchFilter;
propertyChangeSupport.firePropertyChange(SEARCH_FILTER_CHANGED, oldSearchFilter, searchFilter);
}

@Override
public void setStatus(String status) {
String oldStatus = this.status;
this.status = status;
propertyChangeSupport.firePropertyChange(STATUS_CHANGED, oldStatus, status);
}

@Override
public List<BCheck> getAvailableBChecks() {
return allAvailableBChecks;
}

@Override
public List<BCheck> getFilteredBChecks() {
return controller.findMatchingBChecks(searchFilter);
}

@Override
public State state() {
return state;
}

@Override
public void updateModel(List<BCheck> bChecks, State state) {
this.state = state;

allAvailableBChecks.clear();
allAvailableBChecks.addAll(bChecks);
allAvailableBChecks.sort(comparing(BCheck::name));
propertyChangeSupport.firePropertyChange(BCHECKS_UPDATED, null, allAvailableBChecks);

String status = switch (state) {
case START -> "Loading";
case INITIAL_LOAD -> "Loaded %d BCheck scripts".formatted(allAvailableBChecks.size());
case REFRESH -> "Refreshed";
case ERROR -> "Error contacting GitHub repository";
};

setStatus(status);

if (!allAvailableBChecks.contains(selectedBCheck)) {
setSelectedBCheck(null);
}
}

@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
}
64 changes: 64 additions & 0 deletions src/main/java/ui/model/LateInitializationStorefrontModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package ui.model;

import bcheck.BCheck;

import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.function.Supplier;

public class LateInitializationStorefrontModel implements StorefrontModel {
private final Supplier<StorefrontModel> modelSupplier;

public LateInitializationStorefrontModel(Supplier<StorefrontModel> modelSupplier) {
this.modelSupplier = modelSupplier;
}

@Override
public void setSelectedBCheck(BCheck selectedBCheck) {
model().setSelectedBCheck(selectedBCheck);
}

@Override
public BCheck getSelectedBCheck() {
return model().getSelectedBCheck();
}

@Override
public void setSearchFilter(String searchFilter) {
model().setSearchFilter(searchFilter);
}

@Override
public void setStatus(String status) {
model().setStatus(status);
}

@Override
public List<BCheck> getAvailableBChecks() {
return model().getAvailableBChecks();
}

@Override
public List<BCheck> getFilteredBChecks() {
return model().getFilteredBChecks();
}

@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
model().addPropertyChangeListener(listener);
}

@Override
public State state() {
return model().state();
}

@Override
public void updateModel(List<BCheck> bChecks, State state) {
model().updateModel(bChecks, state);
}

private StorefrontModel model() {
return modelSupplier.get();
}
}
12 changes: 12 additions & 0 deletions src/main/java/ui/model/State.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ui.model;

public enum State {
START, INITIAL_LOAD, REFRESH, ERROR;

public State nextState() {
return switch (this) {
case START -> INITIAL_LOAD;
case INITIAL_LOAD, REFRESH, ERROR -> REFRESH;
};
}
}
Loading