Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e2faf9e
Improve XPath export wizard.
oowekyala Nov 22, 2017
6d405ce
Soft reference cache for reusable dialogs
oowekyala Dec 21, 2017
57e9cdd
Fix renamings
oowekyala Jan 13, 2019
3697bda
Replace old XmlTemplater w/ LiveTemplate
oowekyala Jan 18, 2019
d12667a
Add language version selection
oowekyala Jan 21, 2019
321ae8c
Refactor binding logic
oowekyala Jan 22, 2019
cf363ea
Delete old context menu
oowekyala Jan 23, 2019
8342226
Remove dmpwh
oowekyala Jan 23, 2019
cfedf16
Fix checkstyle
oowekyala Jan 23, 2019
0427c68
Use some utilities from rxstring
oowekyala Jan 23, 2019
233f6a3
Fix language version ordering
oowekyala Jan 24, 2019
ae09d2c
Add syntax highlighter on showing
oowekyala Jan 25, 2019
77af4e7
Use released version of live templates
oowekyala Jan 26, 2019
40fd8d6
Add RulePrioritySlider
oowekyala Jan 29, 2019
9bb0098
Fix rebase
oowekyala Feb 27, 2019
bfe26b1
Merge branch 'designer-export-wizard' into new-export-wizard
oowekyala Mar 3, 2019
4761eb1
Fix PMD
oowekyala Mar 3, 2019
ad24a57
Name highlighter threads
oowekyala Mar 3, 2019
b70a800
Merge branch 'master' into new-export-wizard
oowekyala Mar 3, 2019
00fd8cd
Merge branch 'master' into new-export-wizard
oowekyala Mar 6, 2019
ec794e9
Merge branch 'selection-resilience' into new-export-wizard
oowekyala Mar 6, 2019
b3b7828
Rename
oowekyala Mar 6, 2019
d5f6e14
Delete examples pane
oowekyala Mar 6, 2019
24b84dd
Escape message specially
oowekyala Mar 6, 2019
014187c
Merge branch 'master' into new-export-wizard
oowekyala Mar 8, 2019
76c505b
Merge master
oowekyala Mar 8, 2019
23e4c55
Remove accordion animation
oowekyala Mar 8, 2019
2f56f79
Merge branch 'master' into new-export-wizard
oowekyala Mar 10, 2019
27f8e58
Fix syntax highlight not updated
oowekyala Mar 10, 2019
7cc0463
Fix VM hanging on close
oowekyala Mar 10, 2019
cf3f16c
Introduce StageBuilder
oowekyala Mar 10, 2019
50f3158
Merge branch 'master' into new-export-wizard
oowekyala Apr 3, 2019
1f2396a
Fix version
oowekyala Apr 3, 2019
c6266c5
Checkstyle
oowekyala Apr 3, 2019
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
5 changes: 4 additions & 1 deletion .idea/runConfigurations/Designer__JRE_11_.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/runConfigurations/Designer__JRE_9_.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion pmd-ui.iml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.github.oowekyala:fx-live-templates:1.0" level="project" />
<orderEntry type="library" name="Maven: com.github.oowekyala:fx-live-templates:1.0" level="project" />
<orderEntry type="library" name="Maven: com.github.oowekyala:fx-live-templates:1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.openjfx:javafx-base:11" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.openjfx:javafx-base:linux:11" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.openjfx:javafx-controls:11" level="project" />
Expand All @@ -60,6 +63,7 @@
<orderEntry type="library" name="Maven: org.fxmisc.flowless:flowless:0.6" level="project" />
<orderEntry type="library" name="Maven: org.fxmisc.wellbehaved:wellbehavedfx:0.3.3" level="project" />
<orderEntry type="library" name="Maven: org.controlsfx.custom:controlsfx-mr-jar:1.0" level="project" />
<orderEntry type="library" name="Maven: com.github.oowekyala:fx-live-templates:1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
Expand Down Expand Up @@ -136,4 +140,4 @@
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.vintage:junit-vintage-engine:5.4.0" level="project" />
</component>
</module>
</module>
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@
<artifactId>controlsfx-mr-jar</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.github.oowekyala</groupId>
<artifactId>fx-live-templates</artifactId>
<version>1.0</version>
</dependency>

<!-- Those are shaded to avoid duplication -->
<dependency>
Expand All @@ -442,6 +447,7 @@
<version>2.6</version>
</dependency>


<!-- Icon packs -->
<dependency>
<groupId>org.kordamp.ikonli</groupId>
Expand All @@ -463,6 +469,7 @@
<version>${pmd.core.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-apex</artifactId>
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/net/sourceforge/pmd/util/fxdesigner/Designer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.sun.javafx.fxml.builder.ProxyBuilder;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
Expand All @@ -42,7 +43,6 @@ public Designer() {
initStartTimeMillis = System.currentTimeMillis();
}


@Override
public void start(Stage stage) throws IOException {
DesignerParams params = getParameters() == null ? new DesignerParams() : new DesignerParams(getParameters());
Expand Down Expand Up @@ -87,7 +87,13 @@ public void start(Stage stage, DesignerRoot owner) throws IOException {
new SourceEditorController(owner)
));

stage.setOnCloseRequest(e -> mainController.shutdown());
stage.setOnCloseRequest(e -> {
owner.getService(DesignerRoot.PERSISTENCE_MANAGER).persistSettings(mainController);
Platform.exit();
// VM sometimes fails to exit for no apparent reason
// all our threads are killed so it's not our fault
System.exit(0);
});

Parent root = loader.load();
Scene scene = new Scene(root);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ protected void beforeParentInit() {
setupAuxclasspathMenuItem.setOnAction(e -> sourceEditorController.showAuxclasspathSetupPopup());

openEventLogMenuItem.setOnAction(e -> {
EventLogController wizard = eventLogController.getValue();
EventLogController wizard = eventLogController.get();
Subscription parentToWizSubscription = wizard.errorNodesProperty().values().subscribe(sourceEditorController.currentErrorNodesProperty()::setValue);
wizard.showPopup(parentToWizSubscription);
});
Expand All @@ -147,12 +147,6 @@ protected void afterChildrenInit() {
}



public void shutdown() {
getDesignerRoot().getService(DesignerRoot.PERSISTENCE_MANAGER).persistSettings(this);
}


private void onFileMenuShowing() {
openRecentMenu.setDisable(recentFiles.isEmpty());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@


import static net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.sanitizeExceptionMessage;
import static net.sourceforge.pmd.util.fxdesigner.util.reactfx.ReactfxUtil.rewire;
import static net.sourceforge.pmd.util.fxdesigner.util.reactfx.ReactfxUtil.rewireInit;

import java.io.IOException;
import java.time.Duration;
Expand All @@ -25,24 +27,26 @@
import org.controlsfx.validation.Validator;
import org.kordamp.ikonli.javafx.FontIcon;
import org.reactfx.EventStreams;
import org.reactfx.Subscription;
import org.reactfx.SuspendableEventStream;
import org.reactfx.collection.LiveArrayList;
import org.reactfx.value.Val;
import org.reactfx.value.Var;

import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.XPathRule;
import net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery;
import net.sourceforge.pmd.util.fxdesigner.app.AbstractController;
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
import net.sourceforge.pmd.util.fxdesigner.app.services.LogEntry.Category;
import net.sourceforge.pmd.util.fxdesigner.model.ObservableRuleBuilder;
import net.sourceforge.pmd.util.fxdesigner.model.ObservableXPathRuleBuilder;
import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluationException;
import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluator;
import net.sourceforge.pmd.util.fxdesigner.popups.ExportXPathWizardController;
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
import net.sourceforge.pmd.util.fxdesigner.util.SoftReferenceCache;
import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper;
import net.sourceforge.pmd.util.fxdesigner.util.autocomplete.CompletionResultSource;
import net.sourceforge.pmd.util.fxdesigner.util.autocomplete.XPathAutocompleteProvider;
Expand All @@ -54,7 +58,6 @@
import net.sourceforge.pmd.util.fxdesigner.util.controls.PropertyTableView;
import net.sourceforge.pmd.util.fxdesigner.util.controls.ToolbarTitledPane;
import net.sourceforge.pmd.util.fxdesigner.util.controls.XpathViolationListCell;
import net.sourceforge.pmd.util.fxdesigner.util.reactfx.ReactfxUtil;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
Expand All @@ -79,8 +82,11 @@


/**
* XPath panel controller. One such controller is a presenter for an {@link ObservableXPathRuleBuilder},
* which stores all data about one currently edited rule.
* XPath panel controller. This object maintains an {@link ObservableRuleBuilder} which stores information
* about the currently edited rule. The properties of that builder are rewired to the export wizard's fields
* when it's open. The wizard is just one view on the builder's data, which is supposed to offer the most
* customization options. Other views can be implemented in a similar way, for example, PropertyView
* implements a view over the properties of the builder.
*
* @author Clément Fournier
* @see ExportXPathWizardController
Expand All @@ -91,6 +97,7 @@ public class XPathPanelController extends AbstractController implements NodeSele
private static final String NO_MATCH_MESSAGE = "No match in text";
private static final Duration XPATH_REFRESH_DELAY = Duration.ofMillis(100);
private final ObservableXPathRuleBuilder ruleBuilder = new ObservableXPathRuleBuilder();
private final SoftReferenceCache<ExportXPathWizardController> exportWizard;

@FXML
public ToolbarTitledPane expressionTitledPane;
Expand All @@ -116,7 +123,7 @@ public class XPathPanelController extends AbstractController implements NodeSele

public XPathPanelController(DesignerRoot designerRoot) {
super(designerRoot);
getRuleBuilder().setClazz(XPathRule.class);
exportWizard = new SoftReferenceCache<>(() -> new ExportXPathWizardController(designerRoot));
}


Expand Down Expand Up @@ -151,7 +158,10 @@ protected void beforeParentInit() {

@Override
protected void afterParentInit() {
bindToParent();
bindBuilderToPanel();

rewireInit(getRuleBuilder().xpathVersionProperty(), xpathVersionProperty());
rewireInit(getRuleBuilder().xpathExpressionProperty(), xpathExpressionProperty());

// init autocompletion only after binding to parent and settings restore
// otherwise the popup is shown on startup
Expand All @@ -161,17 +171,16 @@ protected void afterParentInit() {


// Binds the underlying rule parameters to the parent UI, disconnecting it from the wizard if need be
private void bindToParent() {
ReactfxUtil.rewire(getRuleBuilder().languageProperty(), Val.map(getGlobalState().globalLanguageVersionProperty(),
LanguageVersion::getLanguage));

ReactfxUtil.rewireInit(getRuleBuilder().xpathVersionProperty(), xpathVersionProperty());
ReactfxUtil.rewireInit(getRuleBuilder().xpathExpressionProperty(), xpathExpressionProperty());
private void bindBuilderToPanel() {
rewire(getRuleBuilder().languageProperty(), Val.map(getGlobalState().globalLanguageVersionProperty(),
LanguageVersion::getLanguage));

ReactfxUtil.rewireInit(getRuleBuilder().rulePropertiesProperty(),
propertyTableView.rulePropertiesProperty(), propertyTableView::setRuleProperties);
rewireInit(getRuleBuilder().rulePropertiesProperty(),
propertyTableView.rulePropertiesProperty(),
propertyTableView::setRuleProperties);
}


private void initialiseVersionSelection() {
ToggleGroup xpathVersionToggleGroup = new ToggleGroup();

Expand Down Expand Up @@ -293,27 +302,21 @@ private void refreshResults() {


public void showExportXPathToRuleWizard() {
ExportXPathWizardController wizard
= new ExportXPathWizardController(xpathExpressionProperty());
ExportXPathWizardController wizard = exportWizard.get();
wizard.showYourself(bindToExportWizard(wizard));
}

FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/xpath-export-wizard.fxml"));
loader.setController(wizard);

final Stage dialog = new Stage();
dialog.initOwner(getDesignerRoot().getMainStage());
dialog.setOnCloseRequest(e -> wizard.shutdown());
dialog.initModality(Modality.WINDOW_MODAL);
/**
* Binds the properties of the panel to the export wizard.
*
* @param exportWizard The caller
*/
private Subscription bindToExportWizard(ExportXPathWizardController exportWizard) {

return exportWizard.bindToRuleBuilder(getRuleBuilder())
.and(this::bindBuilderToPanel);

Parent root;
try {
root = loader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
Scene scene = new Scene(root);
//stage.setTitle("PMD Rule Designer (v " + PMD.VERSION + ')');
dialog.setScene(scene);
dialog.show();
}

public Val<List<Node>> currentResultsProperty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

package net.sourceforge.pmd.util.fxdesigner.app.services;

import static net.sourceforge.pmd.util.fxdesigner.util.reactfx.ReactfxUtil.countNotMatching;

import org.reactfx.collection.LiveList;
import org.reactfx.value.Val;

import com.github.oowekyala.rxstring.ReactfxExtensions;

/**
* Logs events. Stores the whole log in case no view was open.
*
Expand All @@ -19,7 +19,8 @@ public interface EventLogger {

/** Number of log entries that were not yet examined by the user. */
default Val<Integer> numNewLogEntriesProperty() {
return countNotMatching(getLog().map(LogEntry::wasExaminedProperty));
return LiveList.sizeOf(ReactfxExtensions.flattenVals(getLog().map(LogEntry::wasExaminedProperty))
.filtered(read -> !read));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import java.util.Optional;

import org.reactfx.collection.LiveArrayList;
import org.reactfx.collection.LiveList;
import org.reactfx.value.Val;
import org.reactfx.value.Var;

import net.sourceforge.pmd.Rule;
Expand All @@ -19,9 +21,6 @@
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentProperty;
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentSequence;

import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;


Expand All @@ -38,8 +37,8 @@ public class ObservableRuleBuilder implements SettingsOwner {
private final Var<Class<?>> clazz = Var.newSimpleVar(null);

// doesn't contain the "xpath" and "version" properties for XPath rules
private final ListProperty<PropertyDescriptorSpec> ruleProperties = new SimpleListProperty<>(FXCollections.observableArrayList(PropertyDescriptorSpec.extractor()));
private final Var<ObservableList<String>> examples = Var.newSimpleVar(new LiveArrayList<>());
private LiveList<PropertyDescriptorSpec> ruleProperties = new LiveArrayList<>();
private LiveList<String> examples = new LiveArrayList<>();

private final Var<LanguageVersion> minimumVersion = Var.newSimpleVar(null);
private final Var<LanguageVersion> maximumVersion = Var.newSimpleVar(null);
Expand Down Expand Up @@ -106,17 +105,17 @@ public Var<Class<?>> clazzProperty() {

@PersistentSequence
public ObservableList<PropertyDescriptorSpec> getRuleProperties() {
return ruleProperties.getValue();
return ruleProperties;
}


public void setRuleProperties(ObservableList<PropertyDescriptorSpec> ruleProperties) {
this.ruleProperties.setValue(ruleProperties);
this.ruleProperties.setAll(ruleProperties);
}


public ListProperty<PropertyDescriptorSpec> rulePropertiesProperty() {
return ruleProperties;
public Var<ObservableList<PropertyDescriptorSpec>> rulePropertiesProperty() {
return Var.fromVal(Val.constant(ruleProperties), this::setRuleProperties);
}


Expand Down Expand Up @@ -214,13 +213,13 @@ public Var<String> descriptionProperty() {
}


public Var<ObservableList<String>> getExamples() {
public ObservableList<String> getExamples() {
return examples;
}


public void setExamples(ObservableList<String> examples) {
this.examples.setValue(examples);
this.examples.setAll(examples);
}


Expand Down Expand Up @@ -343,8 +342,8 @@ public Optional<Rule> build() throws IllegalArgumentException {
builder.usesTyperesolution(usesTypeResolution.getValue());
builder.usesMultifile(usesMultifile.getValue());

ruleProperties.getValue().stream().map(PropertyDescriptorSpec::build).forEach(builder::defineProperty);
examples.getValue().forEach(builder::addExample);
ruleProperties.stream().map(PropertyDescriptorSpec::build).forEach(builder::defineProperty);
examples.forEach(builder::addExample);

return Optional.of(builder.build());
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
Expand Down
Loading