Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
aQute.bnd.build.model.BndEditModel Maven / Gradle / Ivy
package aQute.bnd.build.model;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.osgi.resource.Requirement;
import aQute.bnd.build.Project;
import aQute.bnd.build.Workspace;
import aQute.bnd.build.model.clauses.ExportedPackage;
import aQute.bnd.build.model.clauses.HeaderClause;
import aQute.bnd.build.model.clauses.ImportPattern;
import aQute.bnd.build.model.clauses.ServiceComponent;
import aQute.bnd.build.model.clauses.VersionedClause;
import aQute.bnd.build.model.conversions.CollectionFormatter;
import aQute.bnd.build.model.conversions.Converter;
import aQute.bnd.build.model.conversions.DefaultBooleanFormatter;
import aQute.bnd.build.model.conversions.DefaultFormatter;
import aQute.bnd.build.model.conversions.EEConverter;
import aQute.bnd.build.model.conversions.EEFormatter;
import aQute.bnd.build.model.conversions.HeaderClauseFormatter;
import aQute.bnd.build.model.conversions.HeaderClauseListConverter;
import aQute.bnd.build.model.conversions.MapFormatter;
import aQute.bnd.build.model.conversions.NewlineEscapedStringFormatter;
import aQute.bnd.build.model.conversions.NoopConverter;
import aQute.bnd.build.model.conversions.PropertiesConverter;
import aQute.bnd.build.model.conversions.PropertiesEntryFormatter;
import aQute.bnd.build.model.conversions.RequirementFormatter;
import aQute.bnd.build.model.conversions.RequirementListConverter;
import aQute.bnd.build.model.conversions.SimpleListConverter;
import aQute.bnd.build.model.conversions.VersionedClauseConverter;
import aQute.bnd.exceptions.Exceptions;
import aQute.bnd.help.instructions.ResolutionInstructions;
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;
import aQute.bnd.properties.LineType;
import aQute.bnd.properties.PropertiesLineReader;
import aQute.bnd.version.Version;
import aQute.lib.collections.Iterables;
import aQute.lib.collections.Logic;
import aQute.lib.io.IO;
import aQute.lib.utf8properties.UTF8Properties;
/**
* A model for a Bnd file.
*
* The bndedit model maintains a Properties that can be modified/added with
* convenient semantic methods and/or properties can be deleted. The bnd file
* tends to be kept in a Processor, and the processors are kept in a inheritance
* chain. The BndEditModel can provide a Processor that extends the original but
* reflects the changes made in the inheritance model.
*/
@SuppressWarnings("deprecation")
public class BndEditModel {
public static final String NEWLINE_LINE_SEPARATOR = "\\n\\\n\t";
public static final String LIST_SEPARATOR = ",\\\n\t";
static String[] KNOWN_PROPERTIES = new String[] {
Constants.BUNDLE_LICENSE, Constants.BUNDLE_CATEGORY, Constants.BUNDLE_NAME, Constants.BUNDLE_DESCRIPTION,
Constants.BUNDLE_COPYRIGHT, Constants.BUNDLE_UPDATELOCATION, Constants.BUNDLE_VENDOR,
Constants.BUNDLE_CONTACTADDRESS, Constants.BUNDLE_DOCURL, Constants.BUNDLE_SYMBOLICNAME,
Constants.BUNDLE_VERSION, Constants.BUNDLE_ACTIVATOR, Constants.EXPORT_PACKAGE, Constants.IMPORT_PACKAGE,
Constants.PRIVATE_PACKAGE, Constants.PRIVATEPACKAGE, Constants.SOURCES, Constants.SERVICE_COMPONENT,
Constants.CLASSPATH, Constants.BUILDPATH, Constants.RUNBUNDLES, Constants.RUNPROPERTIES, Constants.SUB,
Constants.RUNFRAMEWORK, Constants.RUNFW, Constants.RUNVM, Constants.RUNPROGRAMARGS, Constants.DISTRO,
// BndConstants.RUNVMARGS,
// BndConstants.TESTSUITES,
Constants.TESTCASES, Constants.PLUGIN, Constants.PLUGINPATH, Constants.RUNREPOS, Constants.RUNREQUIRES,
Constants.RUNEE, Constants.RUNBLACKLIST, Constants.BUNDLE_BLUEPRINT, Constants.INCLUDE_RESOURCE,
Constants.STANDALONE
};
public static final String PROP_WORKSPACE = "_workspace";
public static final String BUNDLE_VERSION_MACRO = "${"
+ Constants.BUNDLE_VERSION + "}";
static final Map> converters = new HashMap<>();
static final Map> formatters = new HashMap<>();
private final static Converter, String> buildPathConverter = new HeaderClauseListConverter<>(
new Converter() {
@Override
public VersionedClause convert(
HeaderClause input)
throws IllegalArgumentException {
if (input == null)
return null;
return new VersionedClause(
input
.getName(),
input
.getAttribs());
}
@Override
public VersionedClause error(
String msg) {
return null;
}
});
private final static Converter, String> clauseListConverter = new HeaderClauseListConverter<>(
new VersionedClauseConverter());
final static Converter stringConverter = new NoopConverter<>();
private final static Converter includedSourcesConverter = new Converter() {
@Override
public Boolean convert(
String string)
throws IllegalArgumentException {
return Boolean
.valueOf(
string);
}
@Override
public Boolean error(
String msg) {
return Boolean.FALSE;
}
};
private final static Converter, String> listConverter = SimpleListConverter
.create();
private final static Converter, String> exportPackageConverter = new HeaderClauseListConverter<>(
new Converter() {
@Override
public ExportedPackage convert(
HeaderClause input) {
if (input == null)
return null;
return new ExportedPackage(
input
.getName(),
input
.getAttribs());
}
@Override
public ExportedPackage error(
String msg) {
return ExportedPackage
.error(
msg);
}
});
private final static Converter, String> serviceComponentConverter = new HeaderClauseListConverter<>(
new Converter() {
@Override
public ServiceComponent convert(
HeaderClause input)
throws IllegalArgumentException {
if (input == null)
return null;
return new ServiceComponent(
input
.getName(),
input
.getAttribs());
}
@Override
public ServiceComponent error(
String msg) {
return ServiceComponent
.error(
msg);
}
});
private final static Converter, String> importPatternConverter = new HeaderClauseListConverter<>(
new Converter() {
@Override
public ImportPattern convert(
HeaderClause input)
throws IllegalArgumentException {
if (input == null)
return null;
return new ImportPattern(
input
.getName(),
input
.getAttribs());
}
@Override
public ImportPattern error(
String msg) {
return ImportPattern
.error(
msg);
}
});
private final static Converter, String> propertiesConverter = new PropertiesConverter();
private final static Converter, String> requirementListConverter = new RequirementListConverter();
private final static Converter eeConverter = new EEConverter();
// Converter resolveModeConverter =
// EnumConverter.create(ResolveMode.class, ResolveMode.manual);
// FORMATTERS
private final static Converter newlineEscapeFormatter = new NewlineEscapedStringFormatter();
private final static Converter defaultFalseBoolFormatter = new DefaultBooleanFormatter(
false);
private final static Converter> stringListFormatter = new CollectionFormatter<>(
LIST_SEPARATOR, (String) null);
private final static Converter, String> headerClauseListConverter = new HeaderClauseListConverter<>(
new NoopConverter<>());
private final static Converter> headerClauseListFormatter = new CollectionFormatter<>(
LIST_SEPARATOR, new HeaderClauseFormatter(), null);
private final static Converter> complexHeaderClauseListFormatter = new CollectionFormatter<>(
LIST_SEPARATOR, new HeaderClauseFormatter(true), null);
private final static Converter> propertiesFormatter = new MapFormatter(
LIST_SEPARATOR, new PropertiesEntryFormatter(), null);
private final static Converter> requirementListFormatter = new CollectionFormatter<>(
LIST_SEPARATOR, new RequirementFormatter(), null);
private final static Converter> standaloneLinkListFormatter = new CollectionFormatter<>(
LIST_SEPARATOR, new HeaderClauseFormatter(), "");
private final static Converter eeFormatter = new EEFormatter();
private final static Converter> runReposFormatter = new CollectionFormatter<>(
LIST_SEPARATOR, Constants.EMPTY_HEADER);
private File inputFile;
private String name;
private final PropertyChangeSupport propChangeSupport = new PropertyChangeSupport(
this);
private Properties properties = new UTF8Properties();
private final Map objectProperties = new HashMap<>();
private final Map changesToSave = new TreeMap<>();
private Processor owner;
private volatile boolean dirty;
private IDocument document;
private long lastChangedAt;
private Workspace workspace;
// Converter resolveModeFormatter =
// EnumFormatter.create(ResolveMode.class, ResolveMode.manual);
static {
// register converters
converters.put(Constants.BUNDLE_LICENSE, stringConverter);
converters.put(Constants.BUNDLE_CATEGORY, stringConverter);
converters.put(Constants.BUNDLE_NAME, stringConverter);
converters.put(Constants.BUNDLE_DESCRIPTION, stringConverter);
converters.put(Constants.BUNDLE_COPYRIGHT, stringConverter);
converters.put(Constants.BUNDLE_UPDATELOCATION, stringConverter);
converters.put(Constants.BUNDLE_VENDOR, stringConverter);
converters.put(Constants.BUNDLE_CONTACTADDRESS, stringConverter);
converters.put(Constants.BUNDLE_DOCURL, stringConverter);
converters.put(Constants.BUILDPATH, buildPathConverter);
converters.put(Constants.RUNBUNDLES, clauseListConverter);
converters.put(Constants.BUNDLE_SYMBOLICNAME, stringConverter);
converters.put(Constants.BUNDLE_VERSION, stringConverter);
converters.put(Constants.BUNDLE_ACTIVATOR, stringConverter);
converters.put(Constants.OUTPUT, stringConverter);
converters.put(Constants.SOURCES, includedSourcesConverter);
converters.put(Constants.PRIVATE_PACKAGE, listConverter);
converters.put(Constants.PRIVATEPACKAGE, listConverter);
converters.put(Constants.CLASSPATH, listConverter);
converters.put(Constants.EXPORT_PACKAGE, exportPackageConverter);
converters.put(Constants.SERVICE_COMPONENT, serviceComponentConverter);
converters.put(Constants.IMPORT_PACKAGE, importPatternConverter);
converters.put(Constants.RUNFRAMEWORK, stringConverter);
converters.put(Constants.RUNFW, stringConverter);
converters.put(Constants.SUB, listConverter);
converters.put(Constants.RUNPROPERTIES, propertiesConverter);
converters.put(Constants.RUNVM, stringConverter);
converters.put(Constants.RUNPROGRAMARGS, stringConverter);
// converters.put(BndConstants.RUNVMARGS, stringConverter);
converters.put(Constants.TESTCASES, listConverter);
converters.put(Constants.RUNREQUIRES, requirementListConverter);
converters.put(Constants.RUNEE, eeConverter);
converters.put(Constants.RUNREPOS, listConverter);
// converters.put(BndConstants.RESOLVE_MODE, resolveModeConverter);
converters.put(Constants.BUNDLE_BLUEPRINT, headerClauseListConverter);
converters.put(Constants.INCLUDE_RESOURCE, listConverter);
converters.put(Constants.INCLUDERESOURCE, listConverter);
converters.put(Constants.STANDALONE, headerClauseListConverter);
formatters.put(Constants.BUNDLE_LICENSE, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_CATEGORY, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_NAME, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_DESCRIPTION, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_COPYRIGHT, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_UPDATELOCATION, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_VENDOR, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_CONTACTADDRESS, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_DOCURL, newlineEscapeFormatter);
formatters.put(Constants.BUILDPATH, headerClauseListFormatter);
formatters.put(Constants.RUNBUNDLES, headerClauseListFormatter);
formatters.put(Constants.BUNDLE_SYMBOLICNAME, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_VERSION, newlineEscapeFormatter);
formatters.put(Constants.BUNDLE_ACTIVATOR, newlineEscapeFormatter);
formatters.put(Constants.OUTPUT, newlineEscapeFormatter);
formatters.put(Constants.SOURCES, defaultFalseBoolFormatter);
formatters.put(Constants.PRIVATE_PACKAGE, stringListFormatter);
formatters.put(Constants.PRIVATEPACKAGE, stringListFormatter);
formatters.put(Constants.CLASSPATH, stringListFormatter);
formatters.put(Constants.EXPORT_PACKAGE, headerClauseListFormatter);
formatters.put(Constants.SERVICE_COMPONENT, headerClauseListFormatter);
formatters.put(Constants.IMPORT_PACKAGE, headerClauseListFormatter);
formatters.put(Constants.RUNFRAMEWORK, newlineEscapeFormatter);
formatters.put(Constants.RUNFW, newlineEscapeFormatter);
formatters.put(Constants.SUB, stringListFormatter);
formatters.put(Constants.RUNPROPERTIES, propertiesFormatter);
formatters.put(Constants.RUNVM, newlineEscapeFormatter);
formatters.put(Constants.RUNPROGRAMARGS, newlineEscapeFormatter);
// formatters.put(BndConstants.RUNVMARGS, newlineEscapeFormatter);
// formatters.put(BndConstants.TESTSUITES, stringListFormatter);
formatters.put(Constants.TESTCASES, stringListFormatter);
formatters.put(Constants.RUNREQUIRES, requirementListFormatter);
formatters.put(Constants.RUNEE, eeFormatter);
formatters.put(Constants.RUNREPOS, runReposFormatter);
// formatters.put(BndConstants.RESOLVE_MODE, resolveModeFormatter);
formatters.put(Constants.BUNDLE_BLUEPRINT, headerClauseListFormatter);
formatters.put(Constants.INCLUDE_RESOURCE, stringListFormatter);
formatters.put(Constants.INCLUDERESOURCE, stringListFormatter);
formatters.put(Constants.STANDALONE, standaloneLinkListFormatter);
converters.put(Constants.PLUGIN, headerClauseListConverter);
formatters.put(Constants.PLUGIN, complexHeaderClauseListFormatter);
}
/**
* Default constructor
*/
public BndEditModel() {
setOwner(new Processor());
}
/**
* Copy constructor
*
* @param model the source
*/
public BndEditModel(BndEditModel model) {
this.inputFile = model.inputFile;
this.workspace = model.workspace;
this.properties.putAll(model.properties);
this.changesToSave.putAll(model.changesToSave);
setOwner(model.getOwner());
}
public BndEditModel(Workspace workspace) {
this();
this.workspace = workspace;
}
public BndEditModel(IDocument document) throws IOException {
loadFrom(document);
}
public BndEditModel(Workspace workspace, Processor processor) throws IOException {
this(workspace);
this.owner = processor;
this.inputFile = processor.getPropertiesFile();
if (inputFile != null && inputFile.isFile())
this.document = new Document(IO.collect(inputFile));
else
this.document = new Document("");
loadFrom(this.document);
}
public void loadFrom(IDocument document) throws IOException {
try (InputStream in = toEscaped(document.get())) {
loadFrom(in);
}
}
public InputStream toEscaped(String text) throws IOException {
StringReader unicode = new StringReader(text);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
while (true) {
int c = unicode.read();
if (c < 0)
break;
if (c >= 0x7F)
bout.write(String.format("\\u%04X", c)
.getBytes());
else
bout.write((char) c);
}
return new ByteArrayInputStream(bout.toByteArray());
}
public InputStream toAsciiStream(IDocument doc) throws IOException {
saveChangesTo(doc);
return toEscaped(doc.get());
}
public void loadFrom(File file) throws IOException {
loadFrom(IO.stream(file));
}
public void loadFrom(InputStream inputStream) throws IOException {
try {
properties.clear();
properties.load(inputStream);
objectProperties.clear();
changesToSave.clear();
// Fire property changes on all known property names
for (String prop : KNOWN_PROPERTIES) {
// null values for old and new forced the change to be fired
propChangeSupport.firePropertyChange(prop, null, null);
}
} finally {
inputStream.close();
}
}
public void loadFrom(String string) throws IOException {
loadFrom(IO.stream(string));
}
public void saveChangesTo(IDocument document) {
this.lastChangedAt = System.currentTimeMillis();
for (Iterator> iter = changesToSave.entrySet()
.iterator(); iter.hasNext();) {
Entry entry = iter.next();
String propertyName = entry.getKey();
String stringValue = entry.getValue();
updateDocument(document, propertyName, stringValue);
//
// Ensure that properties keeps reflecting the current document
// value
//
String value = cleanup(stringValue);
if (value == null)
value = "";
if (propertyName != null)
properties.setProperty(propertyName, value);
iter.remove();
}
}
private static IRegion findEntry(IDocument document, String name) throws Exception {
PropertiesLineReader reader = new PropertiesLineReader(document);
LineType type = reader.next();
while (type != LineType.eof) {
if (type == LineType.entry) {
String key = reader.key();
if (name.equals(key))
return reader.region();
}
type = reader.next();
}
return null;
}
private static void updateDocument(IDocument document, String name, String value) {
String newEntry;
if (value != null) {
StringBuilder buffer = new StringBuilder();
buffer.append(name)
.append(": ")
.append(value);
newEntry = buffer.toString();
} else {
newEntry = "";
}
try {
IRegion region = findEntry(document, name);
if (region != null) {
// Replace an existing entry
int offset = region.getOffset();
int length = region.getLength();
// If the replacement is empty, remove one extra character to
// the right, i.e. the following newline,
// unless this would take us past the end of the document
if (newEntry.length() == 0 && offset + length + 1 < document.getLength()) {
length++;
}
document.replace(offset, length, newEntry);
} else if (newEntry.length() > 0) {
// This is a new entry, put it at the end of the file
// Does the last line of the document have a newline? If not,
// we need to add one.
if (document.getLength() > 0 && document.getChar(document.getLength() - 1) != '\n')
newEntry = "\n" + newEntry;
document.replace(document.getLength(), 0, newEntry);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public List getAllPropertyNames() {
return StreamSupport.stream(Iterables.iterable(properties.propertyNames(), String.class::cast)
.spliterator(), false)
.collect(toList());
}
public Converter lookupConverter(String propertyName) {
@SuppressWarnings("unchecked")
Converter converter = (Converter) converters.get(propertyName);
return converter;
}
public Converter lookupFormatter(String propertyName) {
@SuppressWarnings("unchecked")
Converter formatter = (Converter) formatters.get(propertyName);
return formatter;
}
public Object genericGet(String propertyName) {
Converter extends Object, String> converter = converters.get(propertyName);
if (converter == null)
converter = new NoopConverter<>();
return doGetObject(propertyName, converter);
}
public void genericSet(String propertyName, Object value) {
Object oldValue = genericGet(propertyName);
@SuppressWarnings("unchecked")
Converter formatter = (Converter) formatters.get(propertyName);
if (formatter == null)
formatter = new DefaultFormatter();
doSetObject(propertyName, oldValue, value, formatter);
}
public String getBundleLicense() {
return doGetObject(Constants.BUNDLE_LICENSE, stringConverter);
}
public void setBundleLicense(String bundleLicense) {
doSetObject(Constants.BUNDLE_LICENSE, getBundleLicense(), bundleLicense, newlineEscapeFormatter);
}
public String getBundleCategory() {
return doGetObject(Constants.BUNDLE_CATEGORY, stringConverter);
}
public void setBundleCategory(String bundleCategory) {
doSetObject(Constants.BUNDLE_CATEGORY, getBundleCategory(), bundleCategory, newlineEscapeFormatter);
}
public String getBundleName() {
return doGetObject(Constants.BUNDLE_NAME, stringConverter);
}
public void setBundleName(String bundleName) {
doSetObject(Constants.BUNDLE_NAME, getBundleName(), bundleName, newlineEscapeFormatter);
}
public String getBundleDescription() {
return doGetObject(Constants.BUNDLE_DESCRIPTION, stringConverter);
}
public void setBundleDescription(String bundleDescription) {
doSetObject(Constants.BUNDLE_DESCRIPTION, getBundleDescription(), bundleDescription, newlineEscapeFormatter);
}
public String getBundleCopyright() {
return doGetObject(Constants.BUNDLE_COPYRIGHT, stringConverter);
}
public void setBundleCopyright(String bundleCopyright) {
doSetObject(Constants.BUNDLE_COPYRIGHT, getBundleCopyright(), bundleCopyright, newlineEscapeFormatter);
}
public String getBundleUpdateLocation() {
return doGetObject(Constants.BUNDLE_UPDATELOCATION, stringConverter);
}
public void setBundleUpdateLocation(String bundleUpdateLocation) {
doSetObject(Constants.BUNDLE_UPDATELOCATION, getBundleUpdateLocation(), bundleUpdateLocation,
newlineEscapeFormatter);
}
public String getBundleVendor() {
return doGetObject(Constants.BUNDLE_VENDOR, stringConverter);
}
public void setBundleVendor(String bundleVendor) {
doSetObject(Constants.BUNDLE_VENDOR, getBundleVendor(), bundleVendor, newlineEscapeFormatter);
}
public String getBundleContactAddress() {
return doGetObject(Constants.BUNDLE_CONTACTADDRESS, stringConverter);
}
public void setBundleContactAddress(String bundleContactAddress) {
doSetObject(Constants.BUNDLE_CONTACTADDRESS, getBundleContactAddress(), bundleContactAddress,
newlineEscapeFormatter);
}
public String getBundleDocUrl() {
return doGetObject(Constants.BUNDLE_DOCURL, stringConverter);
}
public void setBundleDocUrl(String bundleDocUrl) {
doSetObject(Constants.BUNDLE_DOCURL, getBundleDocUrl(), bundleDocUrl, newlineEscapeFormatter);
}
public String getBundleSymbolicName() {
return doGetObject(Constants.BUNDLE_SYMBOLICNAME, stringConverter);
}
public void setBundleSymbolicName(String bundleSymbolicName) {
doSetObject(Constants.BUNDLE_SYMBOLICNAME, getBundleSymbolicName(), bundleSymbolicName, newlineEscapeFormatter);
}
public String getBundleVersionString() {
return doGetObject(Constants.BUNDLE_VERSION, stringConverter);
}
public void setBundleVersion(String bundleVersion) {
doSetObject(Constants.BUNDLE_VERSION, getBundleVersionString(), bundleVersion, newlineEscapeFormatter);
}
public String getBundleActivator() {
return doGetObject(Constants.BUNDLE_ACTIVATOR, stringConverter);
}
public void setBundleActivator(String bundleActivator) {
doSetObject(Constants.BUNDLE_ACTIVATOR, getBundleActivator(), bundleActivator, newlineEscapeFormatter);
}
public String getOutputFile() {
return doGetObject(Constants.OUTPUT, stringConverter);
}
public void setOutputFile(String name) {
doSetObject(Constants.OUTPUT, getOutputFile(), name, newlineEscapeFormatter);
}
public boolean isIncludeSources() {
return doGetObject(Constants.SOURCES, includedSourcesConverter);
}
public void setIncludeSources(boolean includeSources) {
boolean oldValue = isIncludeSources();
doSetObject(Constants.SOURCES, oldValue, includeSources, defaultFalseBoolFormatter);
}
public List getPrivatePackages() {
List privatePackagesEntries1 = getEntries(Constants.PRIVATEPACKAGE, listConverter);
List privatePackagesEntries2 = getEntries(Constants.PRIVATE_PACKAGE, listConverter);
return Stream.concat(privatePackagesEntries1.stream(), privatePackagesEntries2.stream())
.distinct()
.collect(toList());
}
public void setPrivatePackages(List newPackages) {
List privatePackagesEntries1 = getEntries(Constants.PRIVATEPACKAGE, listConverter);
List privatePackagesEntries2 = getEntries(Constants.PRIVATE_PACKAGE, listConverter);
Set privatePackages = Stream.concat(privatePackagesEntries1.stream(), privatePackagesEntries2.stream())
.collect(toSet());
List addedEntries = disjunction(newPackages, privatePackages);
List removedEntries = disjunction(privatePackages, newPackages);
privatePackagesEntries1.removeAll(removedEntries);
if (privatePackagesEntries1.isEmpty()) {
removeEntries(Constants.PRIVATEPACKAGE);
} else {
setEntries(privatePackagesEntries1, Constants.PRIVATEPACKAGE);
}
privatePackagesEntries2.removeAll(removedEntries);
if (privatePackagesEntries2.isEmpty()) {
removeEntries(Constants.PRIVATE_PACKAGE);
} else {
setEntries(privatePackagesEntries2, Constants.PRIVATE_PACKAGE);
}
if (hasPrivatePackageInstruction()) {
privatePackagesEntries1.addAll(addedEntries);
setEntries(privatePackagesEntries1, Constants.PRIVATEPACKAGE);
} else {
privatePackagesEntries2.addAll(addedEntries);
setEntries(privatePackagesEntries2, Constants.PRIVATE_PACKAGE);
}
}
private void setEntries(List extends String> packages, String key) {
List oldPackages = getEntries(key, listConverter);
doSetObject(key, oldPackages, packages, stringListFormatter);
}
private void removeEntries(String key) {
List oldPackages = getEntries(key, listConverter);
doRemoveObject(key, oldPackages, null, stringListFormatter);
}
public void addPrivatePackage(String packageName) {
String key = hasPrivatePackageInstruction() ? Constants.PRIVATEPACKAGE : Constants.PRIVATE_PACKAGE;
List packages = getEntries(key, listConverter);
packages.add(packageName);
setEntries(packages, key);
}
private boolean hasPrivatePackageInstruction() {
return properties.containsKey(Constants.PRIVATEPACKAGE);
}
@SuppressWarnings("unchecked")
private List getEntries(String instruction, Converter extends E, ? super String> converter) {
List entries = (List) doGetObject(instruction, converter);
return entries == null ? new ArrayList<>() : entries;
}
public List getSystemPackages() {
return doGetObject(Constants.RUNSYSTEMPACKAGES, exportPackageConverter);
}
public void setSystemPackages(List extends ExportedPackage> packages) {
List oldPackages = getSystemPackages();
doSetObject(Constants.RUNSYSTEMPACKAGES, oldPackages, packages, headerClauseListFormatter);
}
public List getClassPath() {
return doGetObject(Constants.CLASSPATH, listConverter);
}
public void setClassPath(List extends String> classPath) {
List oldClassPath = getClassPath();
doSetObject(Constants.CLASSPATH, oldClassPath, classPath, stringListFormatter);
}
public List getExportedPackages() {
return doGetObject(Constants.EXPORT_PACKAGE, exportPackageConverter);
}
public void setExportedPackages(List extends ExportedPackage> exports) {
boolean referencesBundleVersion = false;
if (exports != null) {
for (ExportedPackage pkg : exports) {
String versionString = pkg.getVersionString();
if (versionString != null && versionString.contains(BUNDLE_VERSION_MACRO)) {
referencesBundleVersion = true;
}
}
}
List oldValue = getExportedPackages();
doSetObject(Constants.EXPORT_PACKAGE, oldValue, exports, headerClauseListFormatter);
if (referencesBundleVersion && getBundleVersionString() == null) {
setBundleVersion(Version.emptyVersion.toString());
}
}
public void addExportedPackage(ExportedPackage export) {
List exports = getExportedPackages();
exports = (exports == null) ? new ArrayList<>() : new ArrayList<>(exports);
exports.add(export);
setExportedPackages(exports);
}
public List getDSAnnotationPatterns() {
return doGetObject(Constants.DSANNOTATIONS, listConverter);
}
public void setDSAnnotationPatterns(List extends String> patterns) {
List oldValue = getDSAnnotationPatterns();
doSetObject(Constants.DSANNOTATIONS, oldValue, patterns, stringListFormatter);
}
public List getServiceComponents() {
return doGetObject(Constants.SERVICE_COMPONENT, serviceComponentConverter);
}
public void setServiceComponents(List extends ServiceComponent> components) {
List oldValue = getServiceComponents();
doSetObject(Constants.SERVICE_COMPONENT, oldValue, components, headerClauseListFormatter);
}
public List getImportPatterns() {
return doGetObject(Constants.IMPORT_PACKAGE, importPatternConverter);
}
public void setImportPatterns(List extends ImportPattern> patterns) {
List oldValue = getImportPatterns();
doSetObject(Constants.IMPORT_PACKAGE, oldValue, patterns, headerClauseListFormatter);
}
public List getBuildPath() {
return doGetObject(Constants.BUILDPATH, buildPathConverter);
}
public List getTestPath() {
return doGetObject(Constants.TESTPATH, buildPathConverter);
}
public void setBuildPath(List extends VersionedClause> paths) {
List oldValue = getBuildPath();
if (oldValue == null)
oldValue = Collections.emptyList();
doSetObject(Constants.BUILDPATH, oldValue, paths, headerClauseListFormatter);
}
public void addPath(VersionedClause versionedClause, String header) {
List oldValue = doGetObject(header, buildPathConverter);
List newValue = oldValue == null ? new ArrayList<>() : new ArrayList<>(oldValue);
newValue.add(versionedClause);
doSetObject(header, oldValue, newValue, headerClauseListFormatter);
}
public void addPath(BundleId bundleId, String header) {
addPath(new VersionedClause(bundleId), header);
}
public void setTestPath(List extends VersionedClause> paths) {
List oldValue = getTestPath();
doSetObject(Constants.TESTPATH, oldValue, paths, headerClauseListFormatter);
}
public List getRunBundles() {
return doGetObject(Constants.RUNBUNDLES, clauseListConverter);
}
public void setRunBundles(List extends VersionedClause> paths) {
List oldValue = getRunBundles();
doSetObject(Constants.RUNBUNDLES, oldValue, paths, headerClauseListFormatter);
}
public List getRunBundlesDecorator() {
return doGetObject(aQute.bnd.osgi.Constants.RUNBUNDLES_DECORATOR, clauseListConverter);
}
public void setRunBundlesDecorator(List extends VersionedClause> paths) {
List oldValue = getRunBundlesDecorator();
doSetObject(aQute.bnd.osgi.Constants.RUNBUNDLES_DECORATOR, oldValue, paths, headerClauseListFormatter);
}
public boolean isIncludedPackage(String packageName) {
final Collection privatePackages = getPrivatePackages();
if (privatePackages != null) {
if (privatePackages.contains(packageName))
return true;
}
final Collection exportedPackages = getExportedPackages();
if (exportedPackages != null) {
for (ExportedPackage pkg : exportedPackages) {
if (packageName.equals(pkg.getName())) {
return true;
}
}
}
return false;
}
public List getSubBndFiles() {
return doGetObject(Constants.SUB, listConverter);
}
public void setSubBndFiles(List subBndFiles) {
List oldValue = getSubBndFiles();
doSetObject(Constants.SUB, oldValue, subBndFiles, stringListFormatter);
}
public Map getRunProperties() {
return doGetObject(Constants.RUNPROPERTIES, propertiesConverter);
}
/*
* (non-Javadoc)
* @see bndtools.editor.model.IBndModel#setRunProperties(java.util.Map)
*/
public void setRunProperties(Map props) {
Map old = getRunProperties();
doSetObject(Constants.RUNPROPERTIES, old, props, propertiesFormatter);
}
/*
* (non-Javadoc)
* @see bndtools.editor.model.IBndModel#getRunVMArgs()
*/
public String getRunVMArgs() {
return doGetObject(Constants.RUNVM, stringConverter);
}
/*
* (non-Javadoc)
* @see bndtools.editor.model.IBndModel#setRunVMArgs(java.lang.String)
*/
public void setRunVMArgs(String args) {
String old = getRunVMArgs();
doSetObject(Constants.RUNVM, old, args, newlineEscapeFormatter);
}
/*
* (non-Javadoc)
* @see bndtools.editor.model.IBndModel#getRunProgramArgs()
*/
public String getRunProgramArgs() {
return doGetObject(Constants.RUNPROGRAMARGS, stringConverter);
}
/*
* (non-Javadoc)
* @see bndtools.editor.model.IBndModel#setRunProgramArgs(java.lang.String)
*/
public void setRunProgramArgs(String args) {
String old = getRunProgramArgs();
doSetObject(Constants.RUNPROGRAMARGS, old, args, newlineEscapeFormatter);
}
public List getTestSuites() {
List testCases = doGetObject(Constants.TESTCASES, listConverter);
testCases = testCases != null ? testCases : Collections.emptyList();
List result = new ArrayList<>(testCases.size());
result.addAll(testCases);
return result;
}
public void setTestSuites(List suites) {
List old = getTestSuites();
doSetObject(Constants.TESTCASES, old, suites, stringListFormatter);
}
public List getPlugins() {
// return all plugins
// we do prefix matching to support merged properties like
// -plugin.1.Test, -plugin.2.Maven etc.
try {
List propertyKeys = getOwner().getMergePropertyKeys(Constants.PLUGIN);
List headers = PropertyKey.findVisible(propertyKeys)
.stream()
.map(p -> headerClauseListConverter.convert(p.getValue()))
.flatMap(List::stream)
.toList();
return headers;
} catch (Exception e) {
throw Exceptions.duck(e);
}
}
public void setPlugins(List plugins) {
List old = getPlugins();
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.
* -plugin.1.Test, -plugin.2.Maven
The value is a List of
* plugins, although usually it is just a 1-element list. But it is also
* possible to specify multiple plugins under a single key, thus it is a
* list.
*
* @return a map with a property keys and their plugins ( macros like (${.})
* are returned not expanded)
*/
public Map> getPluginsProperties() {
return getPropertiesMapInternal(Constants.PLUGIN, false);
}
/**
* @param stem
* @param expandMacros controls whether or not macros like (${.}) will be
* expanded or not. In the UI when editing the model, macros
* should not be expanded usually (false).
* @return
*/
private Map> getPropertiesMapInternal(String stem, boolean expandMacros) {
try {
Map> map = new LinkedHashMap<>();
Processor processor = getPropertiesInternal(expandMacros);
Set localKeys = processor.getPropertyKeys(false);
List candidates = processor.getMergePropertyKeys(stem);
PropertyKey.findVisible(candidates)
.stream()
.forEach(pk -> {
boolean isLocal = localKeys.contains(pk.key());
List headers = headerClauseListConverter.convert(pk.getValue())
.stream()
.map(h -> new BndEditModelHeaderClause(pk.key(), h, isLocal))
.collect(Collectors.toList());
map.put(pk.key(), headers);
});
return map;
} catch (Exception e) {
throw Exceptions.duck(e);
}
}
/**
* Updates and removes plugins (macros like (${.}) are not expanded).
*
* @param plugins
* @param pluginPropKeysToRemove the property keys to remove (not modified,
* caller needs to handle cleanup)
*/
public void setPlugins(Map> plugins,
Collection pluginPropKeysToRemove) {
setProperties(Constants.PLUGIN, plugins, pluginPropKeysToRemove);
}
private void setProperties(String stem, Map> map,
Collection propKeysToRemove) {
Map> old = getPropertiesMapInternal(stem, false);
map.entrySet()
.stream()
// safety check: filter out properties not starting with the step
.filter(entry -> entry.getKey()
.startsWith(stem))
.forEach(p -> {
List newLocalHeaders = p.getValue()
.stream()
.filter(mh -> mh.isLocal())
.toList();
List oldList = old.get(p.getKey());
List oldLocalHeaders = oldList == null ? null
: oldList.stream()
.filter(mh -> mh.isLocal())
.toList();
if (oldList != null && !isLocalPropertyKey(p.getKey())) {
// skip writing
// existing but non-local means an inherited property
// not from this properties file. so do not write it.
return;
}
doSetObject(p.getKey(), oldLocalHeaders, newLocalHeaders, complexHeaderClauseListFormatter);
});
if (propKeysToRemove != null) {
propKeysToRemove.forEach(key -> removeEntries(key));
}
}
/**
* @param key
* @return true
if the given propertyKey is physically in the
* local {@link #properties}
*/
private boolean isLocalPropertyKey(String key) {
return doGetObject(key, headerClauseListConverter) != null;
}
public List getPluginPath() {
return doGetObject(Constants.PLUGINPATH, listConverter);
}
public void setPluginPath(List pluginPath) {
List old = getPluginPath();
doSetObject(Constants.PLUGINPATH, old, pluginPath, stringListFormatter);
}
public List getDistro() {
return doGetObject(Constants.DISTRO, listConverter);
}
public void setDistro(List distros) {
List old = getPluginPath();
doSetObject(Constants.DISTRO, old, distros, stringListFormatter);
}
public List getRunRepos() {
return doGetObject(Constants.RUNREPOS, listConverter);
}
public void setRunRepos(List repos) {
List old = getRunRepos();
doSetObject(Constants.RUNREPOS, old, repos, runReposFormatter);
}
public String getRunFramework() {
return doGetObject(Constants.RUNFRAMEWORK, stringConverter);
}
public String getRunFw() {
return doGetObject(Constants.RUNFW, stringConverter);
}
public EE getEE() {
return doGetObject(Constants.RUNEE, eeConverter);
}
public void setEE(EE ee) {
EE old = getEE();
doSetObject(Constants.RUNEE, old, ee, eeFormatter);
}
public void setRunFramework(String clause) {
assert (Constants.RUNFRAMEWORK_SERVICES.equalsIgnoreCase(clause.trim())
|| Constants.RUNFRAMEWORK_NONE.equalsIgnoreCase(clause.trim()));
String oldValue = getRunFramework();
doSetObject(Constants.RUNFRAMEWORK, oldValue, clause, newlineEscapeFormatter);
}
public void setRunFw(String clause) {
String oldValue = getRunFw();
doSetObject(Constants.RUNFW, oldValue, clause, newlineEscapeFormatter);
}
public List getRunRequires() {
return doGetObject(Constants.RUNREQUIRES, requirementListConverter);
}
public void setRunRequires(List requires) {
List oldValue = getRunRequires();
doSetObject(Constants.RUNREQUIRES, oldValue, requires, requirementListFormatter);
}
public List getRunBlacklist() {
return doGetObject(Constants.RUNBLACKLIST, requirementListConverter);
}
public void setRunBlacklist(List requires) {
List oldValue = getRunBlacklist();
doSetObject(Constants.RUNBLACKLIST, oldValue, requires, requirementListFormatter);
}
public List getStandaloneLinks() {
return doGetObject(Constants.STANDALONE, headerClauseListConverter);
}
public void setStandaloneLinks(List headers) {
List old = getStandaloneLinks();
doSetObject(Constants.STANDALONE, old, headers, standaloneLinkListFormatter);
}
public List getIgnoreStandalone() {
List v = doGetObject(Constants.IGNORE_STANDALONE, headerClauseListConverter);
if (v != null)
return v;
//
// compatibility fixup
v = doGetObject("x-ignore-standalone", headerClauseListConverter);
if (v == null)
return null;
setIgnoreStandalone(v);
doSetObject("x-ignore-standalone", v, null, standaloneLinkListFormatter);
return doGetObject(Constants.IGNORE_STANDALONE, headerClauseListConverter);
}
public void setIgnoreStandalone(List headers) {
List old = getIgnoreStandalone();
doSetObject(Constants.IGNORE_STANDALONE, old, headers, standaloneLinkListFormatter);
}
private R doGetObject(String name, Converter extends R, ? super String> converter) {
try {
R result;
if (objectProperties.containsKey(name)) {
@SuppressWarnings("unchecked")
R temp = (R) objectProperties.get(name);
result = temp;
} else if (changesToSave.containsKey(name)) {
result = converter.convert(changesToSave.get(name));
objectProperties.put(name, result);
} else if (properties.containsKey(name)) {
result = converter.convert(properties.getProperty(name));
objectProperties.put(name, result);
} else {
result = converter.convert(null);
}
return result;
} catch (Exception e) {
return converter.error(e.getMessage());
}
}
private void doRemoveObject(String name, T oldValue, T newValue, Converter formatter) {
objectProperties.remove(name);
properties.remove(name);
String v = formatter.convert(newValue);
changesToSave.put(name, v);
dirty = true;
propChangeSupport.firePropertyChange(name, oldValue, newValue);
}
private void doSetObject(String name, T oldValue, T newValue, Converter formatter) {
objectProperties.put(name, newValue);
String v = formatter.convert(newValue);
changesToSave.put(name, v);
dirty = true;
propChangeSupport.firePropertyChange(name, oldValue, newValue);
}
public boolean isProjectFile() {
return Project.BNDFILE.equals(getBndResourceName());
}
public boolean isBndrun() {
return getBndResourceName().endsWith(Constants.DEFAULT_BNDRUN_EXTENSION);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propChangeSupport.removePropertyChangeListener(propertyName, listener);
}
public void setBndResource(File bndResource) {
this.inputFile = bndResource;
}
public File getBndResource() {
if (inputFile != null)
return inputFile;
return owner.getPropertiesFile();
}
public String getBndResourceName() {
if (name == null)
return "";
return name;
}
public void setBndResourceName(String bndResourceName) {
this.name = bndResourceName;
}
public List getBundleBlueprint() {
return doGetObject(Constants.BUNDLE_BLUEPRINT, headerClauseListConverter);
}
public void setBundleBlueprint(List bundleBlueprint) {
List old = getPlugins();
doSetObject(Constants.BUNDLE_BLUEPRINT, old, bundleBlueprint, headerClauseListFormatter);
}
public void addBundleBlueprint(String location) {
List bpLocations = getBundleBlueprint();
if (bpLocations == null)
bpLocations = new ArrayList<>();
else
bpLocations = new ArrayList<>(bpLocations);
bpLocations.add(new HeaderClause(location, null));
setBundleBlueprint(bpLocations);
}
public List getIncludeResource() {
List includeResourceEntries1 = getEntries(Constants.INCLUDERESOURCE, listConverter);
List includeResourceEntries2 = getEntries(Constants.INCLUDE_RESOURCE, listConverter);
return Stream.concat(includeResourceEntries1.stream(), includeResourceEntries2.stream())
.distinct()
.collect(toList());
}
@Deprecated
public void setIncludeResource(List newEntries) {
List resourceEntries1 = getEntries(Constants.INCLUDERESOURCE, listConverter).stream()
.toList();
List resourceEntries2 = getEntries(Constants.INCLUDE_RESOURCE, listConverter);
Set resourceEntries = Stream.concat(resourceEntries1.stream(), resourceEntries2.stream())
.collect(toSet());
List addedEntries = disjunction(newEntries, resourceEntries);
List removedEntries = disjunction(resourceEntries, newEntries);
resourceEntries1.removeAll(removedEntries);
if (resourceEntries1.isEmpty()) {
removeEntries(Constants.INCLUDERESOURCE);
} else {
setEntries(resourceEntries1, Constants.INCLUDERESOURCE);
}
resourceEntries2.removeAll(removedEntries);
if (resourceEntries2.isEmpty()) {
removeEntries(Constants.INCLUDE_RESOURCE);
} else {
setEntries(resourceEntries2, Constants.INCLUDE_RESOURCE);
}
if (hasIncludeResourceHeaderLikeInstruction()) {
resourceEntries2.addAll(addedEntries);
setEntries(resourceEntries2, Constants.INCLUDE_RESOURCE);
} else {
resourceEntries1.addAll(addedEntries);
setEntries(resourceEntries1, Constants.INCLUDERESOURCE);
}
}
public void addIncludeResource(String resource) {
String key = hasIncludeResourceHeaderLikeInstruction() ? Constants.INCLUDE_RESOURCE : Constants.INCLUDERESOURCE;
List entries = getEntries(key, listConverter);
entries.add(resource);
setEntries(entries, key);
}
private boolean hasIncludeResourceHeaderLikeInstruction() {
return properties.containsKey(Constants.INCLUDE_RESOURCE);
}
public Project getProject() {
return null;
}
public Workspace getWorkspace() {
return workspace;
}
public void setWorkspace(Workspace workspace) {
Workspace old = this.workspace;
this.workspace = workspace;
propChangeSupport.firePropertyChange(PROP_WORKSPACE, old, workspace);
}
public String getGenericString(String name) {
return doGetObject(name, stringConverter);
}
public void setGenericString(String name, String value) {
doSetObject(name, getGenericString(name), value, stringConverter);
}
/**
* Return a processor for this model. This processor is based on the
* properties of the source processor but with the values of the changed
* properties in this edit model. I.e. the view of the returned processor of
* the properties is the same as when this model would be saved.
*
* The returned processor will use the owner of this model as the parent so
* that all unchanged properties come from the original owner.
*
* When using this method, realize that if you edit a project's bnd.bnd
* file, the returned processor adds an intermediate layer. The
* {@link #owner} is the original Workspace, Project, Bndrun, or sub bnd
* object.
*
* @return a processor that reflects the actual processors setup
*/
public Processor getProperties() throws Exception {
return getPropertiesInternal(true);
}
/**
* @param expandMacros set to true
if macros e.g. '${.}' should
* be expanded. In the UI when editing the model, macros should
* not be expanded usually (false).
* @return a processor that reflects the actual processors setup
* @throws IOException
*/
private Processor getPropertiesInternal(boolean expandMacros) throws IOException {
UTF8Properties currentProperties = new UTF8Properties();
currentProperties.putAll(properties);
if (!changesToSave.isEmpty()) {
String changes = changesToString();
currentProperties.load(changes, null, null);
}
Set ownerLocalKeys = owner.getPropertyKeys(false);
Set editedLocalKeys = currentProperties.keySet()
.stream()
.map(String.class::cast)
.collect(Collectors.toSet());
Collection deleted = Logic.remove(ownerLocalKeys, editedLocalKeys);
Set inheritedKeysWithoutOwner = new HashSet<>(editedLocalKeys);
Processor parent = owner.getParent();
if (parent != null) {
// we leave out the keys of the owner
inheritedKeysWithoutOwner.addAll(parent.getPropertyKeys(true));
}
File source = getBndResource();
Processor dummy = new Processor(owner) {
@Override
public Set getPropertyKeys(boolean inherit) {
if (inherit) {
return Collections.unmodifiableSet(inheritedKeysWithoutOwner);
}
return super.getPropertyKeys(false);
}
@Override
public String getProperty(String key, String deflt, String separator) {
if (!inheritedKeysWithoutOwner.contains(key))
return deflt;
if (expandMacros) {
return super.getProperty(key, deflt, separator);
} else {
return super.getUnprocessedProperty(key, deflt);
}
}
};
dummy.setBase(owner.getBase());
dummy.setPropertiesFile(owner.getPropertiesFile());
if (expandMacros) {
currentProperties = currentProperties.replaceHere(dummy.getBase());
}
dummy.setProperties(currentProperties);
return dummy;
}
String changesToString() {
StringBuilder sb = new StringBuilder();
changesToSave.forEach((key, value) -> sb.append(key)
.append(':')
.append(' ')
.append(value)
.append('\n')
.append('\n'));
return sb.toString();
}
private String cleanup(String value) {
if (value == null)
return null;
return value.replaceAll("\\\\\n", "");
}
private static List disjunction(final Collection collection, final Collection> remove) {
final List list = new ArrayList<>();
for (final E obj : collection) {
if (!remove.contains(obj)) {
list.add(obj);
}
}
return list;
}
/**
* Return the saved changes in document format.
*/
public Map getDocumentChanges() {
return changesToSave;
}
/**
* If this BndEditModel was created with a project then this method will
* save the changes in the document and will store them in the associated
* file.
*
* @throws IOException
*/
public void saveChanges() throws IOException {
assert document != null
&& owner != null : "you can only call saveChanges when you created this edit model with a project";
saveChangesTo(document);
store(document, owner.getPropertiesFile());
dirty = false;
}
public static void store(IDocument document, File file) throws IOException {
IO.store(document.get(), file);
}
public ResolutionInstructions.ResolveMode getResolveMode() {
String resolve = getGenericString(Constants.RESOLVE);
if (resolve != null) {
try {
return aQute.lib.converter.Converter.cnv(ResolutionInstructions.ResolveMode.class, resolve);
} catch (Exception e) {
owner.error("Invalid value for %s: %s. Allowed values are %s", Constants.RESOLVE, resolve,
ResolutionInstructions.ResolveMode.class.getEnumConstants());
}
}
return ResolutionInstructions.ResolveMode.manual;
}
public void setResolveMode(ResolutionInstructions.ResolveMode resolveMode) {
setGenericString(Constants.RESOLVE, resolveMode.name());
}
/**
* @return true if there is a discrepancy between the project's file and the
* document
*/
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean isDirty) {
this.dirty = isDirty;
}
public void load() throws IOException {
loadFrom(inputFile);
}
/**
* If this is on the cnf project
*
* @return true if it is the cnf project
*/
@Deprecated
public boolean isCnf() {
return inputFile != null && Workspace.CNFDIR.equals(inputFile.getParentFile()
.getName()) && Workspace.BUILDFILE.equals(inputFile.getName());
}
/**
* Use the built in formatters to take an unformatted header and turn it
* into a formatted header useful in the editor, for example escaped
* newlines.
*
* @param the intermediate type, doesn't matter
* @param header the name of the instruction
* @param input the source string
* @return the input or a formatted input if there is converter
*/
@SuppressWarnings("unchecked")
public static String format(String header, String input) {
Converter converter = (Converter) converters.get(header);
if (converter == null)
return input;
T converted = converter.convert(input);
Converter formatter = (Converter) formatters.get(header);
return formatter.convert(converted);
}
@SuppressWarnings("unchecked")
public > String add(String header, String toAdd) {
try {
Converter converter = (Converter) converters.get(header);
T last = converter.convert(toAdd);
T oldValue = doGetObject(header, converter);
@SuppressWarnings("rawtypes")
T newValue = (T) last.getClass()
.getConstructor()
.newInstance();
if (oldValue != null)
newValue.addAll(oldValue);
else
oldValue = (T) last.getClass()
.getConstructor()
.newInstance();
newValue.addAll(last);
Converter formatter = (Converter) formatters.get(header);
doSetObject(header, oldValue, newValue, formatter);
return header + ": " + formatter.convert(newValue);
} catch (IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
throw Exceptions.duck(e);
}
}
public long getLastChangedAt() {
return lastChangedAt;
}
public void setOwner(Processor p) {
this.owner = p;
}
public Processor getOwner() {
return owner;
}
public Optional getOwner(Class class1) {
if (class1.isInstance(owner))
return Optional.of(class1.cast(owner));
else
return Optional.empty();
}
public BndEditModel(Project domain) throws IOException {
this(domain.getWorkspace(), domain);
}
@Deprecated
public void setProject(Project project) {
setOwner(project);
}
}