Skip to content

Commit

Permalink
use new PropertyKey + UI improvements
Browse files Browse the repository at this point in the history
- PropertyKey.filterVisible(List<PK> )
- show name + propertyKey.key in plugin list
- hide plugin properties and show as tooltip instead

Signed-off-by: Christoph Rueger <[email protected]>
  • Loading branch information
chrisrueger committed Apr 5, 2024
1 parent 3af8aaa commit cd6147f
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 94 deletions.
75 changes: 41 additions & 34 deletions biz.aQute.bndlib/src/aQute/bnd/build/model/BndEditModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import aQute.bnd.osgi.BundleId;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.Processor.PropertyKey;
import aQute.bnd.properties.Document;
import aQute.bnd.properties.IDocument;
import aQute.bnd.properties.IRegion;
Expand Down Expand Up @@ -402,6 +403,9 @@ public BndEditModel(Project bndrun) throws IOException {
* Workspace/Project/sub bnd files files
*/
Processor getOwner() {
if (bndrun == null)
return new Processor();

File propertiesFile = bndrun.getPropertiesFile();
if (!propertiesFile.getName()
.endsWith(".bnd"))
Expand Down Expand Up @@ -989,13 +993,11 @@ public List<HeaderClause> getPlugins() {
// we do prefix matching to support merged properties like
// -plugin.1.Test, -plugin.2.Maven etc.
try {
Processor proc = getProperties();
Properties allProps = proc.getProperties();
Set<String> propertyKeys = proc.getPropertyKeys(true);
List<PropertyKey> propertyKeys = getOwner().getMergePropertyKeys(Constants.PLUGIN);

List<HeaderClause> headers = propertyKeys.stream()
.filter(p -> p.startsWith(Constants.PLUGIN))
.map(p -> headerClauseListConverter.convert(allProps.getProperty(p)))
List<HeaderClause> headers = PropertyKey.findVisible(propertyKeys)
.stream()
.map(p -> headerClauseListConverter.convert(p.getValue()))
.flatMap(List::stream)
.toList();

Expand All @@ -1012,6 +1014,8 @@ public void setPlugins(List<HeaderClause> plugins) {
doSetObject(Constants.PLUGIN, old, plugins, complexHeaderClauseListFormatter);
}



/**
* Similar to {@link #getPlugins()} but returns a map where the key is the
* property key of the bnd file e.g.
Expand All @@ -1022,29 +1026,31 @@ public void setPlugins(List<HeaderClause> plugins) {
*
* @return a map with a property keys and their plugins.
*/
public Map<String, List<MergedHeaderClause>> getPluginsProperties() {
// return all plugins
// we do prefix matching to support merged properties like
public Map<String, List<BndEditModelHeaderClause>> getPluginsProperties() {
return getProperties(Constants.PLUGIN);
}

private Map<String, List<BndEditModelHeaderClause>> getProperties(String stem) {
// return all properties
// we do step prefix-matching to support merged properties. e.g.
// stem=-plugin hould return
// -plugin.1.Test, -plugin.2.Maven etc.

try {
Processor proc = getProperties();
Properties allProps = proc.getProperties();
Set<String> propertyKeys = proc.getPropertyKeys(true);

Map<String, List<BndEditModelHeaderClause>> map = new LinkedHashMap<>();

Map<String, List<MergedHeaderClause>> map = new LinkedHashMap<>();
PropertyKey.findVisible(getOwner().getMergePropertyKeys(stem))
.stream()
.forEach(pk -> {

propertyKeys.stream()
.filter(p -> p.startsWith(Constants.PLUGIN))
.forEach(key -> {
boolean isLocal = doGetObject(pk.key(), headerClauseListConverter) != null;

boolean isLocal = doGetObject(key, headerClauseListConverter) != null;

List<HeaderClause> headers = headerClauseListConverter.convert(allProps.getProperty(key));
map.put(key, headers.stream()
.map(h -> new MergedHeaderClause(key, h, isLocal))
.collect(Collectors.toList()));
List<BndEditModelHeaderClause> headers = headerClauseListConverter.convert(pk.getValue())
.stream()
.map(h -> new BndEditModelHeaderClause(pk.key(), h, isLocal))
.collect(Collectors.toList());
map.put(pk.key(), headers);

});

Expand All @@ -1063,27 +1069,26 @@ public Map<String, List<MergedHeaderClause>> getPluginsProperties() {
* @param pluginPropKeysToRemove the property keys to remove (not modified,
* caller needs to handle cleanup)
*/
public void setPlugins(Map<String, List<MergedHeaderClause>> plugins, Collection<String> pluginPropKeysToRemove) {
Map<String, List<MergedHeaderClause>> old = getPluginsProperties();
public void setPlugins(Map<String, List<BndEditModelHeaderClause>> plugins,
Collection<String> pluginPropKeysToRemove) {
setProperties(plugins, pluginPropKeysToRemove);
}

private void setProperties(Map<String, List<BndEditModelHeaderClause>> map,
Collection<String> pluginPropKeysToRemove) {
Map<String, List<BndEditModelHeaderClause>> old = getProperties(Constants.PLUGIN);

plugins.entrySet()
map.entrySet()
.forEach(p -> {
if (!p.getKey()
.startsWith(Constants.PLUGIN)) {
throw new IllegalArgumentException(
"Plugin properties need to start with " + Constants.PLUGIN + ". Actual: " + p.getKey());
}

List<HeaderClause> newLocalHeaders = p.getValue()
List<BndEditModelHeaderClause> newLocalHeaders = p.getValue()
.stream()
.filter(mh -> mh.isLocal())
.map(mh -> mh.header())
.toList();

List<HeaderClause> oldLocalHeaders = old.get(p.getKey())
List<BndEditModelHeaderClause> oldLocalHeaders = old.get(p.getKey())
.stream()
.filter(mh -> mh.isLocal())
.map(mh -> mh.header())
.toList();

doSetObject(p.getKey(), oldLocalHeaders, newLocalHeaders,
Expand All @@ -1096,6 +1101,8 @@ public void setPlugins(Map<String, List<MergedHeaderClause>> plugins, Collection
}
}



public List<String> getPluginPath() {
return doGetObject(Constants.PLUGINPATH, listConverter);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package aQute.bnd.build.model;

import aQute.bnd.build.model.clauses.HeaderClause;

/**
* This is a special {@link HeaderClause} which knows from which property-key it
* came from. Also it has knowledge about if it <i>isLocal</i>. local means that
* it is in the current file you are looking it (vs. inherited via
* mergedProperties)
*/
public class BndEditModelHeaderClause extends HeaderClause {

private String propertyKey;
private boolean isLocal;

public BndEditModelHeaderClause(String propertyKey, HeaderClause headerClause, boolean isLocal) {
super(headerClause.getName(), headerClause.getAttribs());
this.propertyKey = propertyKey;
this.isLocal = isLocal;
}

public String key() {
return propertyKey;
}

public boolean isLocal() {
return isLocal;
}


public String displayTitle() {
return attribs.get("name", getName());
}
}
26 changes: 0 additions & 26 deletions biz.aQute.bndlib/src/aQute/bnd/build/model/MergedHeaderClause.java

This file was deleted.

17 changes: 17 additions & 0 deletions biz.aQute.bndlib/src/aQute/bnd/osgi/Processor.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -1051,6 +1052,22 @@ public int compareTo(PropertyKey o) {
return n;
return Integer.compare(floor, o.floor);
}

/**
* Find visible property keys. "Visible" in this context means that
* among the {@code PropertyKey} objects with the same key, only the one
* with the lowest floor number is included in the result.
*
* @param keys sorted keys defined by {@link #compareTo(PropertyKey)}
* @return only unique keys which are visible (lowest floor value)
*/
public static Collection<PropertyKey> findVisible(Collection<PropertyKey> keys) {
Map<String, PropertyKey> map = new LinkedHashMap<>();
for (PropertyKey pk : keys) {
map.putIfAbsent(pk.key(), pk);
}
return new LinkedHashSet<>(map.values());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import aQute.bnd.build.model.MergedHeaderClause;
import aQute.bnd.build.model.clauses.HeaderClause;
import aQute.bnd.build.model.BndEditModelHeaderClause;
import bndtools.Plugin;

public class PluginClauseLabelProvider extends StyledCellLabelProvider {
Expand All @@ -28,26 +27,29 @@ public PluginClauseLabelProvider(Map<String, IConfigurationElement> configElemen

@Override
public void update(ViewerCell cell) {
MergedHeaderClause mh = (MergedHeaderClause) cell.getElement();
HeaderClause header = mh.header();
BndEditModelHeaderClause header = (BndEditModelHeaderClause) cell.getElement();

String className = header.getName();
String displayTitle = header.displayTitle();

StyledString label = new StyledString(className, mh.isLocal() ? null : StyledString.QUALIFIER_STYLER);
StyledString label = new StyledString(displayTitle,
header.isLocal() ? null : StyledString.QUALIFIER_STYLER);

Map<String, String> attribs = header.getAttribs();
if (!attribs.isEmpty())
label.append(" ");
for (Iterator<Entry<String, String>> iter = attribs.entrySet()
.iterator(); iter.hasNext();) {
Entry<String, String> entry = iter.next();
label.append(entry.getKey(), StyledString.QUALIFIER_STYLER);
label.append("=", StyledString.QUALIFIER_STYLER);
label.append(entry.getValue(), StyledString.COUNTER_STYLER);
label.append(" (" + header.key() + ": " + className + ")", StyledString.QUALIFIER_STYLER);

if (iter.hasNext())
label.append(", ");
}
// Map<String, String> attribs = header.getAttribs();
// if (!attribs.isEmpty())
// label.append(" ");
// for (Iterator<Entry<String, String>> iter = attribs.entrySet()
// .iterator(); iter.hasNext();) {
// Entry<String, String> entry = iter.next();
// label.append(entry.getKey(), StyledString.QUALIFIER_STYLER);
// label.append("=", StyledString.QUALIFIER_STYLER);
// label.append(entry.getValue(), StyledString.COUNTER_STYLER);
//
// if (iter.hasNext())
// label.append(", ");
// }

cell.setText(label.toString());
cell.setStyleRanges(label.getStyleRanges());
Expand Down Expand Up @@ -80,8 +82,27 @@ public void update(ViewerCell cell) {

@Override
public String getToolTipText(Object element) {
if (element instanceof MergedHeaderClause mh && !mh.isLocal()) {
return "This inherited plugin can only be edited in the included .bnd file.";

if (element instanceof BndEditModelHeaderClause header) {
StringBuilder sb = new StringBuilder();

Map<String, String> attribs = header.getAttribs();
for (Iterator<Entry<String, String>> iter = attribs.entrySet()
.iterator(); iter.hasNext();) {
Entry<String, String> entry = iter.next();
sb.append(entry.getKey());
sb.append("=");
sb.append(entry.getValue());

if (iter.hasNext())
sb.append("\n");
}

if (!header.isLocal()) {
return "This inherited plugin can only be edited in the included .bnd file. \n\n" + sb.toString();
}

return sb.toString();
}
return super.getToolTipText(element);
}
Expand Down
Loading

0 comments on commit cd6147f

Please sign in to comment.