Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleCapability.java21
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java9
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java188
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/namespaces/EquinoxNativeEnvironmentNamespace.java8
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/AliasMapper.java38
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java253
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java11
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java21
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java16
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/core/Tokenizer.java18
10 files changed, 315 insertions, 268 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleCapability.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleCapability.java
index d94b14f64..1d388021a 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleCapability.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleCapability.java
@@ -10,7 +10,8 @@
*******************************************************************************/
package org.eclipse.osgi.container;
-import java.util.Map;
+import java.util.*;
+import org.eclipse.osgi.container.namespaces.EquinoxNativeEnvironmentNamespace;
import org.osgi.framework.wiring.BundleCapability;
/**
@@ -21,12 +22,14 @@ public final class ModuleCapability implements BundleCapability {
private final String namespace;
private final Map<String, String> directives;
private final Map<String, Object> attributes;
+ private final Map<String, Object> transientAttrs;
private final ModuleRevision revision;
ModuleCapability(String namespace, Map<String, String> directives, Map<String, Object> attributes, ModuleRevision revision) {
this.namespace = namespace;
this.directives = directives;
this.attributes = attributes;
+ this.transientAttrs = EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE.equals(namespace) ? new HashMap<String, Object>(0) : null;
this.revision = revision;
}
@@ -47,9 +50,25 @@ public final class ModuleCapability implements BundleCapability {
@Override
public Map<String, Object> getAttributes() {
+ if (transientAttrs == null)
+ return attributes;
+ Map<String, Object> result = new HashMap<String, Object>(transientAttrs);
+ result.putAll(attributes);
+ return Collections.unmodifiableMap(result);
+ }
+
+ Map<String, Object> getPersistentAttributes() {
return attributes;
}
+ public void setTransientAttrs(Map<String, ?> transientAttrs) {
+ if (transientAttrs == null) {
+ throw new UnsupportedOperationException(namespace + ": namespace does not support transient attributes."); //$NON-NLS-1$
+ }
+ this.transientAttrs.clear();
+ this.transientAttrs.putAll(transientAttrs);
+ }
+
@Override
public ModuleRevision getResource() {
return revision;
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
index 570c9fd25..988b79a43 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
@@ -28,7 +28,8 @@ import org.eclipse.osgi.internal.container.ComputeNodeOrder;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.*;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Wire;
import org.osgi.service.resolver.Resolver;
/**
@@ -1092,11 +1093,11 @@ public class ModuleDatabase {
writeVersion(current.getVersion(), out);
out.writeInt(current.getTypes());
- List<Capability> capabilities = current.getCapabilities(null);
+ List<ModuleCapability> capabilities = current.getModuleCapabilities(null);
out.writeInt(capabilities.size());
- for (Capability capability : capabilities) {
+ for (ModuleCapability capability : capabilities) {
out.writeInt(addToWriteTable(capability, objectTable));
- writeGenericInfo(capability.getNamespace(), capability.getAttributes(), capability.getDirectives(), out);
+ writeGenericInfo(capability.getNamespace(), capability.getPersistentAttributes(), capability.getDirectives(), out);
}
List<Requirement> requirements = current.getRequirements(null);
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java
index 90b5fa7a5..9751f40b0 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java
@@ -17,7 +17,9 @@ import org.eclipse.osgi.container.ModuleRevisionBuilder;
import org.eclipse.osgi.container.namespaces.*;
import org.eclipse.osgi.framework.internal.core.Msg;
import org.eclipse.osgi.framework.internal.core.Tokenizer;
-import org.eclipse.osgi.internal.framework.*;
+import org.eclipse.osgi.internal.framework.EquinoxContainer;
+import org.eclipse.osgi.internal.framework.FilterImpl;
+import org.eclipse.osgi.storage.Storage;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
@@ -732,35 +734,124 @@ public final class OSGiManifestBuilderFactory {
return new String[] {eeName, v1};
}
+ static class NativeClause implements Comparable<NativeClause> {
+ private final int manifestIndex;
+ final List<String> nativePaths;
+ final String filter;
+ private final Version highestFloor;
+ private final boolean hasLanguage;
+
+ NativeClause(int manifestIndex, ManifestElement clause) throws BundleException {
+ this.manifestIndex = manifestIndex;
+ this.nativePaths = new ArrayList<String>(Arrays.asList(clause.getValueComponents()));
+ StringBuilder sb = new StringBuilder();
+ sb.append("(&"); //$NON-NLS-1$
+ addToNativeCodeFilter(sb, clause, Constants.BUNDLE_NATIVECODE_OSNAME);
+ addToNativeCodeFilter(sb, clause, Constants.BUNDLE_NATIVECODE_PROCESSOR);
+ this.highestFloor = (Version) addToNativeCodeFilter(sb, clause, Constants.BUNDLE_NATIVECODE_OSVERSION);
+ this.hasLanguage = ((Boolean) addToNativeCodeFilter(sb, clause, Constants.BUNDLE_NATIVECODE_LANGUAGE)).booleanValue();
+ String selectionFilter = clause.getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE);
+ if (selectionFilter != null) {
+ sb.append(selectionFilter);
+ }
+ sb.append(')');
+ this.filter = sb.toString();
+ }
+
+ private static Object addToNativeCodeFilter(StringBuilder filter, ManifestElement nativeCode, String attribute) throws BundleException {
+ Boolean hasLanguage = Boolean.FALSE;
+ Version highestFloor = null;
+ String[] attrValues = nativeCode.getAttributes(attribute);
+ if (attrValues != null) {
+
+ String filterAttribute = attribute;
+ if (Constants.BUNDLE_NATIVECODE_OSNAME.equals(attribute)) {
+ filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_NAME_ATTRIBUTE;
+ } else if (Constants.BUNDLE_NATIVECODE_PROCESSOR.equals(attribute)) {
+ filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE;
+ } else if (Constants.BUNDLE_NATIVECODE_LANGUAGE.equals(attribute)) {
+ filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE;
+ hasLanguage = attrValues.length > 0;
+ } else if (Constants.BUNDLE_NATIVECODE_OSVERSION.equals(attribute)) {
+ filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_VERSION_ATTRIBUTE;
+ }
+
+ if (attrValues.length > 1) {
+ filter.append("(|"); //$NON-NLS-1$
+ }
+ for (String attrAlias : attrValues) {
+ if (EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_VERSION_ATTRIBUTE.equals(filterAttribute)) {
+ VersionRange range = new VersionRange(attrAlias);
+ if (highestFloor == null || highestFloor.compareTo(range.getLeft()) < 0) {
+ highestFloor = range.getLeft();
+ }
+ filter.append(range.toFilterString(filterAttribute));
+ } else {
+ try {
+ filter.append('(').append(filterAttribute).append("~=").append(Storage.sanitizeFilterInput(attrAlias)).append(')'); //$NON-NLS-1$
+ } catch (InvalidSyntaxException e) {
+ throw new BundleException("Bad native attribute: " + attrAlias, e); //$NON-NLS-1$
+ }
+ }
+ }
+ if (attrValues.length > 1) {
+ filter.append(')');
+ }
+ }
+ return Constants.BUNDLE_NATIVECODE_LANGUAGE.equals(attribute) ? hasLanguage : highestFloor;
+ }
+
+ @Override
+ public int compareTo(NativeClause other) {
+ if (this.highestFloor != null) {
+ if (other == null) {
+ return -1;
+ }
+ int compareVersions = this.highestFloor.compareTo(other.highestFloor);
+ if (compareVersions != 0) {
+ return -(compareVersions);
+ }
+ } else if (other.highestFloor != null) {
+ return 1;
+ }
+ if (this.hasLanguage) {
+ return other.hasLanguage ? other.manifestIndex - this.manifestIndex : 1;
+ }
+ return other.hasLanguage ? -1 : other.manifestIndex - this.manifestIndex;
+ }
+ }
+
private static void getNativeCode(ModuleRevisionBuilder builder, Map<String, String> manifest) throws BundleException {
ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_NATIVECODE, manifest.get(Constants.BUNDLE_NATIVECODE));
if (elements == null) {
return;
}
- boolean optional = elements.length > 0 && elements[elements.length - 1].getValue().equals("*"); //$NON-NLS-1$
+ boolean optional = false;
+
+ List<NativeClause> nativeClauses = new ArrayList<NativeClause>();
+ for (int i = 0; i < elements.length; i++) {
+ if (i == elements.length - 1) {
+ optional = elements[i].getValue().equals("*"); //$NON-NLS-1$
+ }
+ if (!optional) {
+ nativeClauses.add(new NativeClause(i, elements[i]));
+ }
+ }
+ Collections.sort(nativeClauses);
- AliasMapper aliasMapper = new AliasMapper();
- List<List<String>> allNativePaths = new ArrayList<List<String>>();
- List<String> allSelectionFilters = new ArrayList<String>(0);
+ Map<String, Object> attributes = new HashMap<String, Object>(2);
+ int numNativePaths = nativeClauses.size();
StringBuilder allNativeFilters = new StringBuilder();
allNativeFilters.append("(|"); //$NON-NLS-1$
- for (ManifestElement nativeCode : elements) {
- allNativePaths.add(new ArrayList<String>(Arrays.asList(nativeCode.getValueComponents())));
-
- StringBuilder filter = new StringBuilder();
- filter.append("(&"); //$NON-NLS-1$
- addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_OSNAME, aliasMapper);
- addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_PROCESSOR, aliasMapper);
- addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_OSVERSION, aliasMapper);
- addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_LANGUAGE, aliasMapper);
- filter.append(')');
-
- allNativeFilters.append(filter.toString());
- String selectionFilter = nativeCode.getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE);
- if (selectionFilter != null) {
- allSelectionFilters.add(selectionFilter);
+ for (int i = 0; i < numNativePaths; i++) {
+ NativeClause nativeClause = nativeClauses.get(i);
+ if (numNativePaths == 1) {
+ attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE, nativeClause.nativePaths);
+ } else {
+ attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE + '.' + i, nativeClause.nativePaths);
}
+ allNativeFilters.append(nativeClauses.get(i).filter);
}
allNativeFilters.append(')');
@@ -770,63 +861,6 @@ public final class OSGiManifestBuilderFactory {
directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, EquinoxNativeEnvironmentNamespace.RESOLUTION_OPTIONAL);
}
- Map<String, Object> attributes = new HashMap<String, Object>(0);
- int i = 0;
- int numNativePaths = allNativePaths.size();
- for (List<String> nativePaths : allNativePaths) {
- if (numNativePaths == 0) {
- attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE, nativePaths);
- } else {
- attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE + '.' + i, nativePaths);
- }
- i++;
- }
-
- if (!allSelectionFilters.isEmpty()) {
- StringBuilder selectionFilter = new StringBuilder();
- selectionFilter.append("(|"); //$NON-NLS-1$
- for (String filter : allSelectionFilters) {
- selectionFilter.append(filter);
- }
- selectionFilter.append(")"); //$NON-NLS-1$
- directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_SELECTION_FILTER_DIRECTIVE, selectionFilter.toString());
- }
builder.addRequirement(EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE, directives, attributes);
}
-
- private static void addToNativeCodeFilter(StringBuilder filter, ManifestElement nativeCode, String attribute, AliasMapper aliasMapper) {
- String[] attrValues = nativeCode.getAttributes(attribute);
- Collection<String> attrAliases = new HashSet<String>(1);
- if (attrValues != null) {
- for (String attrValue : attrValues) {
- if (Constants.BUNDLE_NATIVECODE_OSNAME.equals(attribute) || Constants.BUNDLE_NATIVECODE_PROCESSOR.equals(attribute)) {
- attrValue = attrValue.toLowerCase();
- }
- attrAliases.add(attrValue);
- }
- }
- String filterAttribute = attribute;
- if (Constants.BUNDLE_NATIVECODE_OSNAME.equals(attribute)) {
- filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_NAME_ATTRIBUTE;
- } else if (Constants.BUNDLE_NATIVECODE_PROCESSOR.equals(attribute)) {
- filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE;
- } else if (Constants.BUNDLE_NATIVECODE_LANGUAGE.equals(attribute)) {
- filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE;
- } else if (Constants.BUNDLE_NATIVECODE_OSVERSION.equals(attribute)) {
- filterAttribute = EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_VERSION_ATTRIBUTE;
- }
- if (attrAliases.size() > 1) {
- filter.append("(|"); //$NON-NLS-1$
- }
- for (String attrAlias : attrAliases) {
- if (EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_VERSION_ATTRIBUTE.equals(filterAttribute)) {
- filter.append(new VersionRange(attrAlias).toFilterString(filterAttribute));
- } else {
- filter.append('(').append(filterAttribute).append('=').append(attrAlias).append(')');
- }
- }
- if (attrAliases.size() > 1) {
- filter.append(')');
- }
- }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/namespaces/EquinoxNativeEnvironmentNamespace.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/namespaces/EquinoxNativeEnvironmentNamespace.java
index 3219b584b..25ff8c1cd 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/namespaces/EquinoxNativeEnvironmentNamespace.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/namespaces/EquinoxNativeEnvironmentNamespace.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.osgi.container.namespaces;
-import org.osgi.framework.Constants;
import org.osgi.resource.Namespace;
/**
@@ -69,11 +68,4 @@ public class EquinoxNativeEnvironmentNamespace extends Namespace {
* The value of this attribute must be of type {@code List<String>}.
*/
public static final String REQUIREMENT_NATIVE_PATHS_ATTRIBUTE = "native.paths"; //$NON-NLS-1$
-
- /**
- * Specifies the arbitrary selection filter for the native code requirement. This filter
- * is matched against the system properties.
- * @see Constants#SELECTION_FILTER_ATTRIBUTE
- */
- public static final String REQUIREMENT_SELECTION_FILTER_DIRECTIVE = "selection.filter"; //$NON-NLS-1$
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/AliasMapper.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/AliasMapper.java
index 1cf09526c..963793757 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/AliasMapper.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/AliasMapper.java
@@ -12,6 +12,7 @@ package org.eclipse.osgi.internal.framework;
import java.io.*;
import java.util.*;
+import java.util.Map.Entry;
import org.eclipse.osgi.framework.internal.core.Tokenizer;
import org.eclipse.osgi.internal.debug.Debug;
@@ -90,7 +91,7 @@ public class AliasMapper {
* @param in InputStream from which to read alias data.
* @return Map of aliases.
*/
- protected static Map<String, Collection<String>> initAliases(InputStream in, Map<String, Collection<String>> aliasTable, Map<String, String> canonicalTable) {
+ private static Map<String, Collection<String>> initAliases(InputStream in, Map<String, Collection<String>> aliasTable, Map<String, String> canonicalTable) {
try {
BufferedReader br;
try {
@@ -98,6 +99,7 @@ public class AliasMapper {
} catch (UnsupportedEncodingException e) {
br = new BufferedReader(new InputStreamReader(in));
}
+ Map<String, Set<String>> multiMaster = new HashMap<String, Set<String>>();
while (true) {
String line = br.readLine();
if (line == null) /* EOF */{
@@ -109,36 +111,40 @@ public class AliasMapper {
String masterLower = master.toLowerCase();
canonicalTable.put(masterLower, master);
Collection<String> aliasLine = new ArrayList<String>(1);
- aliasLine.add(masterLower);
+ aliasLine.add(master);
parseloop: while (true) {
String alias = tokenizer.getString("# \t"); //$NON-NLS-1$
if (alias == null) {
break parseloop;
}
+ aliasLine.add(alias);
String aliasLower = alias.toLowerCase();
- aliasLine.add(aliasLower);
if (!canonicalTable.containsKey(aliasLower)) {
canonicalTable.put(aliasLower, master);
} else {
// the alias has multiple masters just make its canonical name be the alias
- canonicalTable.put(aliasLower, alias);
- }
- }
- for (String alias : aliasLine) {
- Collection<String> aliases = aliasTable.get(alias);
- if (aliases == null) {
- aliases = new ArrayList<String>(aliasLine);
- aliasTable.put(alias, aliases);
- } else {
- for (String aliasToAdd : aliasLine) {
- if (!aliases.contains(aliasToAdd)) {
- aliases.add(aliasToAdd);
- }
+ String existingMaster = canonicalTable.put(aliasLower, alias);
+ Set<String> masters = multiMaster.get(aliasLower);
+ if (masters == null) {
+ masters = new HashSet<String>();
+ multiMaster.put(aliasLower, masters);
+ masters.add(existingMaster.toLowerCase());
}
+ masters.add(masterLower);
}
}
+ aliasTable.put(masterLower, aliasLine);
+ }
+ }
+ Map<String, Set<String>> multiMasterAliases = new HashMap<String, Set<String>>(multiMaster.size());
+ for (Entry<String, Set<String>> entry : multiMaster.entrySet()) {
+ Set<String> aliases = new HashSet<String>();
+ for (String master : entry.getValue()) {
+ aliases.addAll(aliasTable.get(master));
}
+ multiMasterAliases.put(entry.getKey(), aliases);
}
+ aliasTable.putAll(multiMasterAliases);
} catch (IOException e) {
Debug.printStackTrace(e);
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java
index 97fcc1ead..aa5088474 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java
@@ -10,6 +10,17 @@
*******************************************************************************/
package org.eclipse.osgi.internal.framework;
+import static org.osgi.framework.Constants.FRAMEWORK_LANGUAGE;
+import static org.osgi.framework.Constants.FRAMEWORK_OS_NAME;
+import static org.osgi.framework.Constants.FRAMEWORK_OS_VERSION;
+import static org.osgi.framework.Constants.FRAMEWORK_PROCESSOR;
+import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN;
+import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT;
+import static org.osgi.framework.Constants.FRAMEWORK_VENDOR;
+import static org.osgi.framework.Constants.SUPPORTS_FRAMEWORK_EXTENSION;
+import static org.osgi.framework.Constants.SUPPORTS_FRAMEWORK_FRAGMENT;
+import static org.osgi.framework.Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE;
+
import java.io.*;
import java.lang.reflect.Method;
import java.net.*;
@@ -52,11 +63,8 @@ public class EquinoxConfiguration implements EnvironmentInfo {
public static final String VARIABLE_DELIM_STRING = "$"; //$NON-NLS-1$
public static final char VARIABLE_DELIM_CHAR = '$';
+ private final Map<String, String> initialConfig;
private final Properties configuration;
- private final String nl;
- private final String os;
- private final String ws;
- private final String arch;
private final Debug debug;
private final DebugOptions debugOptions;
@@ -169,9 +177,12 @@ public class EquinoxConfiguration implements EnvironmentInfo {
public static final String PROP_FORCED_RESTART = "osgi.forcedRestart"; //$NON-NLS-1$
- EquinoxConfiguration(Map<String, String> initialConfig, HookRegistry hookRegistry) {
+ private final static Collection<String> populateInitConfig = Arrays.asList(PROP_OSGI_ARCH, PROP_OSGI_OS, PROP_OSGI_WS, PROP_OSGI_NL, FRAMEWORK_OS_NAME, FRAMEWORK_OS_VERSION, FRAMEWORK_PROCESSOR, FRAMEWORK_LANGUAGE);
+
+ EquinoxConfiguration(Map<String, String> initialConfiguration, HookRegistry hookRegistry) {
+ this.initialConfig = initialConfiguration == null ? new HashMap<String, String>(0) : new HashMap<String, String>(initialConfiguration);
this.hookRegistry = hookRegistry;
- String useSystemPropsValue = initialConfig == null ? null : initialConfig.get(PROP_USE_SYSTEM_PROPERTIES);
+ String useSystemPropsValue = initialConfig.get(PROP_USE_SYSTEM_PROPERTIES);
boolean useSystemProps = useSystemPropsValue == null ? false : Boolean.parseBoolean(useSystemPropsValue);
this.configuration = useSystemProps ? System.getProperties() : new Properties();
if (useSystemProps) {
@@ -179,91 +190,25 @@ public class EquinoxConfiguration implements EnvironmentInfo {
for (Map.Entry<String, String> configEntry : initialConfig.entrySet()) {
if (!this.configuration.containsKey(configEntry.getKey())) {
this.configuration.put(configEntry.getKey(), configEntry.getValue());
+ } else {
+ // override the initial config value
+ Object systemValue = this.configuration.get(configEntry.getKey());
+ if (systemValue instanceof String) {
+ configEntry.setValue((String) systemValue);
+ }
}
}
} else {
this.configuration.putAll(initialConfig);
}
- initializeProperties(this.configuration, aliasMapper);
- /*
- * Initializes the execution context for this run of the platform. The context
- * includes information about the locale, operating system and window system.
- *
- * NOTE: The OS, WS, and ARCH values should never be null. The executable should
- * be setting these values and therefore this code path is obsolete for Eclipse
- * when run from the executable.
- */
- // if the user didn't set the locale with a command line argument then use the default.
- String nlValue = configuration.getProperty(PROP_OSGI_NL);
- if (nlValue != null) {
- StringTokenizer tokenizer = new StringTokenizer(nlValue, "_"); //$NON-NLS-1$
- int segments = tokenizer.countTokens();
- try {
- Locale userLocale = null;
- switch (segments) {
- case 1 :
- // use the 2 arg constructor to maintain compatibility with 1.3.1
- userLocale = new Locale(tokenizer.nextToken(), ""); //$NON-NLS-1$
- break;
- case 2 :
- userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
- break;
- case 3 :
- userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken(), tokenizer.nextToken());
- break;
- default :
- // if the user passed us in a bogus value then log a message and use the default
- System.err.println(NLS.bind(EclipseAdaptorMsg.error_badNL, nlValue));
- userLocale = Locale.getDefault();
- break;
- }
- Locale.setDefault(userLocale);
- // TODO what the heck is this for?? why not just use osgi.nl
- configuration.put(PROP_OSGI_NL_USER, nlValue);
- } catch (NoSuchElementException e) {
- // fall through and use the default
+ initializeProperties(this.configuration, aliasMapper);
+ for (String initialKey : populateInitConfig) {
+ String value = this.configuration.getProperty(initialKey);
+ if (value != null) {
+ this.initialConfig.put(initialKey, value);
}
}
- nlValue = Locale.getDefault().toString();
- configuration.put(PROP_OSGI_NL, nlValue);
-
- // if the user didn't set the operating system with a command line
- // argument then use the default.
- String osValue = configuration.getProperty(PROP_OSGI_OS);
- if (osValue == null) {
- osValue = guessOS(System.getProperty(PROP_JVM_OS_NAME));
- configuration.put(PROP_OSGI_OS, osValue);
- }
-
- // if the user didn't set the window system with a command line
- // argument then use the default.
- String wsValue = configuration.getProperty(PROP_OSGI_WS);
- if (wsValue == null) {
- wsValue = guessWS(osValue);
- configuration.put(PROP_OSGI_WS, wsValue);
- }
-
- // if the user didn't set the system architecture with a command line
- // argument then use the default.
- String archValue = configuration.getProperty(PROP_OSGI_ARCH);
- if (archValue == null) {
- String name = System.getProperty(PROP_JVM_OS_ARCH);
- // Map i386 architecture to x86
- if (name.equalsIgnoreCase(INTERNAL_ARCH_I386))
- archValue = Constants.ARCH_X86;
- // Map amd64 architecture to x86_64
- else if (name.equalsIgnoreCase(INTERNAL_AMD64))
- archValue = Constants.ARCH_X86_64;
- else
- archValue = name;
- configuration.put(PROP_OSGI_ARCH, archValue);
- }
-
- nl = nlValue;
- os = osValue;
- ws = wsValue;
- arch = archValue;
this.debugOptions = new FrameworkDebugOptions(this);
this.debug = new Debug(this.debugOptions);
@@ -305,8 +250,8 @@ public class EquinoxConfiguration implements EnvironmentInfo {
if (libExtensions[i].length() > 0 && libExtensions[i].charAt(0) != '.')
libExtensions[i] = '.' + libExtensions[i];
LIB_EXTENSIONS = Collections.unmodifiableList(Arrays.asList(libExtensions));
- ECLIPSE_LIB_VARIANTS = buildEclipseLibraryVariants(ws, os, arch, nl);
- ECLIPSE_NL_JAR_VARIANTS = buildNLJarVariants(nl);
+ ECLIPSE_LIB_VARIANTS = buildEclipseLibraryVariants(getWS(), getOS(), getOSArch(), getNL());
+ ECLIPSE_NL_JAR_VARIANTS = buildNLJarVariants(getNL());
DEFINE_PACKAGE_ATTRIBUTES = !"noattributes".equals(configuration.getProperty(PROP_DEFINE_PACKAGES)); //$NON-NLS-1$
String bsnVersion = configuration.getProperty(org.osgi.framework.Constants.FRAMEWORK_BSNVERSION);
@@ -326,19 +271,8 @@ public class EquinoxConfiguration implements EnvironmentInfo {
PARALLEL_CAPABLE = CLASS_LOADER_TYPE_PARALLEL.equals(getConfiguration(PROP_CLASS_LOADER_TYPE));
}
- public Map<String, String> asMap() {
- Map<String, String> result = new HashMap<String, String>();
- synchronized (configuration) {
- for (Object key : configuration.keySet()) {
- if (key instanceof String) {
- Object value = configuration.get(key);
- if (value instanceof String) {
- result.put((String) key, (String) value);
- }
- }
- }
- }
- return result;
+ public Map<String, String> getInitialConfig() {
+ return Collections.unmodifiableMap(initialConfig);
}
private static List<String> buildEclipseLibraryVariants(String ws, String os, String arch, String nl) {
@@ -397,19 +331,19 @@ public class EquinoxConfiguration implements EnvironmentInfo {
}
public String getOSArch() {
- return arch;
+ return this.configuration.getProperty(PROP_OSGI_ARCH);
}
public String getNL() {
- return nl;
+ return this.configuration.getProperty(PROP_OSGI_NL);
}
public String getOS() {
- return os;
+ return this.configuration.getProperty(PROP_OSGI_OS);
}
public String getWS() {
- return ws;
+ return this.configuration.getProperty(PROP_OSGI_WS);
}
public void setAllArgs(String[] allArgs) {
@@ -607,6 +541,19 @@ public class EquinoxConfiguration implements EnvironmentInfo {
}
}
+ void mergeConfiguration(Properties source) {
+ for (Enumeration<?> e = source.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String value = source.getProperty(key);
+ if (getConfiguration(key) == null) {
+ setProperty(key, value);
+ initialConfig.put(key, value);
+ } else {
+ initialConfig.put(key, getConfiguration(key));
+ }
+ }
+ }
+
private static void initializeProperties(Properties configuration, AliasMapper aliasMapper) {
// initialize some framework properties that must always be set
if (configuration.get(PROP_FRAMEWORK) == null || configuration.get(EquinoxLocations.PROP_INSTALL_AREA) == null) {
@@ -626,24 +573,24 @@ public class EquinoxConfiguration implements EnvironmentInfo {
configuration.put(PROP_FRAMEWORK, decode(configuration.getProperty(PROP_FRAMEWORK)));
configuration.put(EquinoxLocations.PROP_INSTALL_AREA, decode(configuration.getProperty(EquinoxLocations.PROP_INSTALL_AREA)));
- configuration.put(org.osgi.framework.Constants.FRAMEWORK_VENDOR, ECLIPSE_FRAMEWORK_VENDOR);
- String value = configuration.getProperty(org.osgi.framework.Constants.FRAMEWORK_PROCESSOR);
+ configuration.put(FRAMEWORK_VENDOR, ECLIPSE_FRAMEWORK_VENDOR);
+ String value = configuration.getProperty(FRAMEWORK_PROCESSOR);
if (value == null) {
value = System.getProperty(PROP_JVM_OS_ARCH);
if (value != null) {
- configuration.put(org.osgi.framework.Constants.FRAMEWORK_PROCESSOR, aliasMapper.getCanonicalProcessor(value));
+ configuration.put(FRAMEWORK_PROCESSOR, aliasMapper.getCanonicalProcessor(value));
}
}
- value = configuration.getProperty(org.osgi.framework.Constants.FRAMEWORK_OS_NAME);
+ value = configuration.getProperty(FRAMEWORK_OS_NAME);
if (value == null) {
value = System.getProperty(PROP_JVM_OS_NAME);
if (value != null) {
- configuration.put(org.osgi.framework.Constants.FRAMEWORK_OS_NAME, aliasMapper.getCanonicalOSName(value));
+ configuration.put(FRAMEWORK_OS_NAME, aliasMapper.getCanonicalOSName(value));
}
}
- value = configuration.getProperty(org.osgi.framework.Constants.FRAMEWORK_OS_VERSION);
+ value = configuration.getProperty(FRAMEWORK_OS_VERSION);
if (value == null) {
value = System.getProperty(PROP_JVM_OS_VERSION);
if (value != null) {
@@ -682,20 +629,96 @@ public class EquinoxConfiguration implements EnvironmentInfo {
// must be an invalid qualifier; just ignore it
value = new Version(major, minor, micro).toString();
}
- configuration.put(org.osgi.framework.Constants.FRAMEWORK_OS_VERSION, value);
+ configuration.put(FRAMEWORK_OS_VERSION, value);
}
}
- value = configuration.getProperty(org.osgi.framework.Constants.FRAMEWORK_LANGUAGE);
+ value = configuration.getProperty(FRAMEWORK_LANGUAGE);
if (value == null)
// set the value of the framework language property
- configuration.put(org.osgi.framework.Constants.FRAMEWORK_LANGUAGE, Locale.getDefault().getLanguage());
+ configuration.put(FRAMEWORK_LANGUAGE, Locale.getDefault().getLanguage());
// set the support properties for fragments and require-bundle (bug 173090)
- configuration.put(org.osgi.framework.Constants.SUPPORTS_FRAMEWORK_FRAGMENT, "true"); //$NON-NLS-1$
- configuration.put(org.osgi.framework.Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, "true"); //$NON-NLS-1$
- configuration.put(org.osgi.framework.Constants.SUPPORTS_FRAMEWORK_EXTENSION, "true"); //$NON-NLS-1$
- if (org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT.equals(configuration.get(org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN))) {
+ configuration.put(SUPPORTS_FRAMEWORK_FRAGMENT, "true"); //$NON-NLS-1$
+ configuration.put(SUPPORTS_FRAMEWORK_REQUIREBUNDLE, "true"); //$NON-NLS-1$
+ configuration.put(SUPPORTS_FRAMEWORK_EXTENSION, "true"); //$NON-NLS-1$
+ if (FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT.equals(configuration.get(FRAMEWORK_STORAGE_CLEAN))) {
configuration.put(PROP_CLEAN, "true"); //$NON-NLS-1$
}
+
+ /*
+ * Initializes the execution context for this run of the platform. The context
+ * includes information about the locale, operating system and window system.
+ *
+ * NOTE: The OS, WS, and ARCH values should never be null. The executable should
+ * be setting these values and therefore this code path is obsolete for Eclipse
+ * when run from the executable.
+ */
+
+ // if the user didn't set the locale with a command line argument then use the default.
+ String nlValue = configuration.getProperty(PROP_OSGI_NL);
+ if (nlValue != null) {
+ StringTokenizer tokenizer = new StringTokenizer(nlValue, "_"); //$NON-NLS-1$
+ int segments = tokenizer.countTokens();
+ try {
+ Locale userLocale = null;
+ switch (segments) {
+ case 1 :
+ // use the 2 arg constructor to maintain compatibility with 1.3.1
+ userLocale = new Locale(tokenizer.nextToken(), ""); //$NON-NLS-1$
+ break;
+ case 2 :
+ userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
+ break;
+ case 3 :
+ userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken(), tokenizer.nextToken());
+ break;
+ default :
+ // if the user passed us in a bogus value then log a message and use the default
+ System.err.println(NLS.bind(EclipseAdaptorMsg.error_badNL, nlValue));
+ userLocale = Locale.getDefault();
+ break;
+ }
+ Locale.setDefault(userLocale);
+ // TODO what the heck is this for?? why not just use osgi.nl
+ configuration.put(PROP_OSGI_NL_USER, nlValue);
+ } catch (NoSuchElementException e) {
+ // fall through and use the default
+ }
+ }
+ nlValue = Locale.getDefault().toString();
+ configuration.put(PROP_OSGI_NL, nlValue);
+
+ // if the user didn't set the operating system with a command line
+ // argument then use the default.
+ String osValue = configuration.getProperty(PROP_OSGI_OS);
+ if (osValue == null) {
+ osValue = guessOS(System.getProperty(PROP_JVM_OS_NAME));
+ configuration.put(PROP_OSGI_OS, osValue);
+ }
+
+ // if the user didn't set the window system with a command line
+ // argument then use the default.
+ String wsValue = configuration.getProperty(PROP_OSGI_WS);
+ if (wsValue == null) {
+ wsValue = guessWS(osValue);
+ configuration.put(PROP_OSGI_WS, wsValue);
+ }
+
+ // if the user didn't set the system architecture with a command line
+ // argument then use the default.
+ String archValue = configuration.getProperty(PROP_OSGI_ARCH);
+ if (archValue == null) {
+ String name = System.getProperty(PROP_JVM_OS_ARCH);
+ // Map i386 architecture to x86
+ if (name.equalsIgnoreCase(INTERNAL_ARCH_I386))
+ archValue = Constants.ARCH_X86;
+ // Map amd64 architecture to x86_64
+ else if (name.equalsIgnoreCase(INTERNAL_AMD64))
+ archValue = Constants.ARCH_X86_64;
+ else
+ archValue = name;
+ configuration.put(PROP_OSGI_ARCH, archValue);
+ }
+
}
private static int parseVersionInt(String value) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
index 5db495da0..dfb97e596 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
@@ -116,16 +116,7 @@ public class EquinoxContainer {
} catch (MalformedURLException e) {
// its ok. This should never happen
}
- mergeProperties(equinoxConfig, loadProperties(location, equinoxConfig));
- }
-
- private static void mergeProperties(EquinoxConfiguration equinoxConfig, Properties source) {
- for (Enumeration<?> e = source.keys(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- String value = source.getProperty(key);
- if (equinoxConfig.getConfiguration(key) == null)
- equinoxConfig.setProperty(key, value);
- }
+ equinoxConfig.mergeConfiguration(loadProperties(location, equinoxConfig));
}
private static Properties loadProperties(URL location, EquinoxConfiguration equinoxConfig) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java
index 7c49560da..61020d4bc 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java
@@ -15,7 +15,6 @@ import java.security.PrivilegedAction;
import java.util.*;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.container.ModuleCollisionHook;
-import org.eclipse.osgi.container.namespaces.EquinoxNativeEnvironmentNamespace;
import org.eclipse.osgi.framework.internal.core.Msg;
import org.eclipse.osgi.internal.baseadaptor.ArrayMap;
import org.eclipse.osgi.internal.debug.Debug;
@@ -263,10 +262,6 @@ class OSGiFrameworkHooks {
if (debug.DEBUG_HOOKS) {
Debug.println("ResolverHook.filterMatches(" + requirement + ", " + candidates + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
-
- // always filter the native code namespace
- filterNativeSelectionFilter(requirement, candidates);
-
if (hooks.isEmpty())
return;
candidates = new ShrinkableCollection<BundleCapability>(candidates);
@@ -284,22 +279,6 @@ class OSGiFrameworkHooks {
}
}
- private void filterNativeSelectionFilter(BundleRequirement requirement, Collection<BundleCapability> candidates) {
- if (EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE.equals(requirement.getNamespace())) {
- String filterSpec = requirement.getDirectives().get(EquinoxNativeEnvironmentNamespace.REQUIREMENT_SELECTION_FILTER_DIRECTIVE);
- if (filterSpec != null) {
- try {
- Filter f = FilterImpl.newInstance(filterSpec);
- if (!f.matches(container.getConfiguration().asMap())) {
- candidates.clear();
- }
- } catch (InvalidSyntaxException e) {
- candidates.clear();
- }
- }
- }
- }
-
public void end() {
if (debug.DEBUG_HOOKS) {
Debug.println("ResolverHook.end"); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
index 03ace286f..75851b874 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
@@ -209,6 +209,12 @@ public class Storage {
throw new IllegalStateException("Could not create a builder for the system bundle.", e); //$NON-NLS-1$
}
}
+ ModuleRevision currentRevision = systemModule.getCurrentRevision();
+ List<ModuleCapability> nativeEnvironments = currentRevision.getModuleCapabilities(EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE);
+ Map<String, String> configMap = equinoxContainer.getConfiguration().getInitialConfig();
+ for (ModuleCapability nativeEnvironment : nativeEnvironments) {
+ nativeEnvironment.setTransientAttrs(configMap);
+ }
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
@@ -512,16 +518,14 @@ public class Storage {
result.append(EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE).append("; "); //$NON-NLS-1$
if (osName != null) {
osName = getAliasList(equinoxConfig.getAliasMapper().getOSNameAliases(osName));
- result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_NAME_ATTRIBUTE).append(":List<String>=").append(osName).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_NAME_ATTRIBUTE).append(":List<String>=").append(osName).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
}
if (processor != null) {
processor = getAliasList(equinoxConfig.getAliasMapper().getProcessorAliases(processor));
result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE).append(":List<String>=").append(processor).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
}
- result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_VERSION_ATTRIBUTE).append(":Version").append("=").append(osVersion).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE).append("=").append(language); //$NON-NLS-1$
- // TODO need a way to configure in arbitrary native code matching attributes
-
+ result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_OS_VERSION_ATTRIBUTE).append(":Version").append("=\"").append(osVersion).append("\"; "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ result.append(EquinoxNativeEnvironmentNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE).append("=\"").append(language).append('\"'); //$NON-NLS-1$
return result.toString();
}
@@ -1418,7 +1422,7 @@ public class Storage {
return pathList;
}
- private static String sanitizeFilterInput(String filePattern) throws InvalidSyntaxException {
+ public static String sanitizeFilterInput(String filePattern) throws InvalidSyntaxException {
StringBuffer buffer = null;
boolean foundEscape = false;
for (int i = 0; i < filePattern.length(); i++) {
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/core/Tokenizer.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/core/Tokenizer.java
index 2cbf602d9..33310209a 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/core/Tokenizer.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/core/Tokenizer.java
@@ -110,7 +110,6 @@ public class Tokenizer {
StringBuffer sb = new StringBuffer();
cur++; /* skip quote */
char c = '\0';
- int begin = cur;
for (; cur < max; cur++) {
c = val[cur];
// this is an escaped char
@@ -126,19 +125,18 @@ public class Tokenizer {
}
sb.append(c);
}
- int count = cur - begin;
+
if (c == '\"') {
cur++;
- }
+ } // TODO else error; no closing quote?
+
cursor = cur;
- if (count > 0) {
- skipWhiteSpace();
- return sb.toString();
- }
- } else /* not a quoted string; same as token */
- {
- return getToken(terminals);
+ skipWhiteSpace();
+ return sb.toString();
+
}
+ /* not a quoted string; same as token */
+ return getToken(terminals);
}
return (null);
}

Back to the top