Skip to content

Commit

Permalink
Modernize internal p2 metadata Member classes
Browse files Browse the repository at this point in the history
This improves the Requirement.hashCode() method.
  • Loading branch information
HannesWell committed Oct 8, 2023
1 parent b9af23d commit 67d4cd6
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 385 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2017 IBM Corporation and others.
* Copyright (c) 2007, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -13,17 +13,16 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata;

import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Objects;
import org.eclipse.core.runtime.Assert;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.expression.IMemberProvider;

/**
/**
* The concrete type for representing IArtifactKey's.
* <p>
* See {link IArtifact for a description of the lifecycle of artifact keys)
* See {link IArtifact for a description of the lifecycle of artifact keys)
*/
public class ArtifactKey implements IArtifactKey, IMemberProvider {
private static final String SEPARATOR = ","; //$NON-NLS-1$
Expand All @@ -36,52 +35,33 @@ public class ArtifactKey implements IArtifactKey, IMemberProvider {
private final String classifier;
private final Version version;

private static String[] getArrayFromList(String stringList, String separator) {
if (stringList == null || stringList.trim().length() == 0)
return new String[0];
ArrayList<String> list = new ArrayList<>();
boolean separatorSeen = true;
StringTokenizer tokens = new StringTokenizer(stringList, separator, true);
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
if (token.equals(separator)) {
if (separatorSeen)
list.add(""); //$NON-NLS-1$
separatorSeen = true;
} else {
separatorSeen = false;
if (token.length() != 0)
list.add(token);
}
}
if (separatorSeen)
list.add(""); //$NON-NLS-1$
return list.toArray(new String[list.size()]);
}

public static IArtifactKey parse(String specification) {
String[] parts = getArrayFromList(specification, SEPARATOR);
if (parts.length < 2 || parts.length > 3)
String[] parts = specification.split(SEPARATOR, -1);
if (parts.length < 2 || parts.length > 3) {
throw new IllegalArgumentException("Unexpected number of parts in artifact key: " + specification); //$NON-NLS-1$
}
Version version = Version.emptyVersion;
if (parts.length == 3 && parts[2].trim().length() > 0)
if (parts.length == 3 && !parts[2].isBlank()) {
version = Version.parseVersion(parts[2]);
}
try {
return new ArtifactKey(parts[0], parts[1], version);
} catch (IllegalArgumentException e) {
throw (IllegalArgumentException) new IllegalArgumentException("Wrong version syntax in artifact key: " + specification).initCause(e); //$NON-NLS-1$
throw (IllegalArgumentException) new IllegalArgumentException(
"Wrong version syntax in artifact key: " + specification).initCause(e); //$NON-NLS-1$
}
}

public ArtifactKey(String classifier, String id, Version version) {
super();
Assert.isNotNull(classifier);
Assert.isNotNull(id);
Assert.isNotNull(version);
if (classifier.contains(SEPARATOR))
if (classifier.contains(SEPARATOR)) {
throw new IllegalArgumentException("comma not allowed in classifier"); //$NON-NLS-1$
if (id.contains(SEPARATOR))
}
if (id.contains(SEPARATOR)) {
throw new IllegalArgumentException("comma not allowed in id"); //$NON-NLS-1$
}
this.classifier = classifier;
this.id = id;
this.version = version;
Expand All @@ -105,10 +85,7 @@ public Version getVersion() {

@Override
public int hashCode() {
int hash = id.hashCode();
hash = 17 * hash + getVersion().hashCode();
hash = 17 * hash + classifier.hashCode();
return hash;
return Objects.hash(id, getVersion(), classifier);
}

@Override
Expand All @@ -118,10 +95,9 @@ public String toString() {

@Override
public boolean equals(Object obj) {
if (!(obj instanceof IArtifactKey))
return false;
IArtifactKey ak = (IArtifactKey) obj;
return ak.getId().equals(id) && ak.getVersion().equals(getVersion()) && ak.getClassifier().equals(classifier);
return obj instanceof IArtifactKey ak //
&& ak.getId().equals(id) && ak.getVersion().equals(getVersion())
&& ak.getClassifier().equals(classifier);
}

@Override
Expand All @@ -131,24 +107,16 @@ public String getId() {

@Override
public String toExternalForm() {
StringBuffer data = new StringBuffer(classifier).append(SEPARATOR);
data.append(id).append(SEPARATOR);
data.append(version.toString());
return data.toString();
return String.join(SEPARATOR, classifier, id, version.toString());
}

@Override
public Object getMember(String memberName) {
// It is OK to use identity comparisons here since
// a) All constant valued strings are always interned
// b) The Member constructor always interns the name
//
if (MEMBER_ID == memberName)
return id;
if (MEMBER_VERSION == memberName)
return version;
if (MEMBER_CLASSIFIER == memberName)
return classifier;
throw new IllegalArgumentException("No such member: " + memberName); //$NON-NLS-1$
return switch (memberName) {
case MEMBER_ID -> id;
case MEMBER_VERSION -> version;
case MEMBER_CLASSIFIER -> classifier;
default -> throw new IllegalArgumentException("No such member: " + memberName); //$NON-NLS-1$
};
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2018 IBM Corporation and others.
* Copyright (c) 2007, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -16,9 +16,11 @@

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
Expand Down Expand Up @@ -108,44 +110,33 @@ public InstallableUnit() {

public void addTouchpointData(ITouchpointData newData) {
int tl = touchpointData.length;
if (tl == 0)
if (tl == 0) {
touchpointData = new ITouchpointData[] { newData };
else {
} else {
ITouchpointData[] newDatas = new ITouchpointData[tl + 1];
System.arraycopy(touchpointData, 0, newDatas, 0, tl);
newDatas[tl] = newData;
touchpointData = newDatas;
}
}

static final Comparator<IInstallableUnit> ID_FIRST_THEN_VERSION = Comparator //
.comparing(IInstallableUnit::getId) //
.thenComparing(IInstallableUnit::getVersion);

@Override
public int compareTo(IInstallableUnit other) {
int cmp = getId().compareTo(other.getId());
if (cmp == 0)
cmp = getVersion().compareTo(other.getVersion());
return cmp;
return ID_FIRST_THEN_VERSION.compare(this, other);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (obj == null)
return false;
if (!(obj instanceof IInstallableUnit))
return false;
final IInstallableUnit other = (IInstallableUnit) obj;
if (id == null) {
if (other.getId() != null)
return false;
} else if (!id.equals(other.getId()))
return false;
if (getVersion() == null) {
if (other.getVersion() != null)
return false;
} else if (!getVersion().equals(other.getVersion()))
return false;
return true;
}
return obj instanceof IInstallableUnit unit //
&& Objects.equals(getId(), unit.getId()) //
&& Objects.equals(getVersion(), unit.getVersion());
}

@Override
Expand Down Expand Up @@ -183,10 +174,7 @@ public Map<String, String> getProperties() {
* Helper method to cache localized properties
*/
public String getLocalizedProperty(String key) {
String result = null;
if (localizedProperties != null)
result = localizedProperties.getProperty(key);
return result;
return localizedProperties != null ? localizedProperties.getProperty(key) : null;
}

@Override
Expand Down Expand Up @@ -227,11 +215,7 @@ public Version getVersion() {

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((getVersion() == null) ? 0 : getVersion().hashCode());
return result;
return Objects.hash(id, getVersion());
}

@Override
Expand All @@ -245,21 +229,15 @@ public boolean isSingleton() {
}

private OrderedProperties properties() {
return (properties != null ? properties : NO_PROPERTIES);
return properties != null ? properties : NO_PROPERTIES;
}

public void setArtifacts(IArtifactKey[] value) {
if (value == null || value.length == 0)
artifacts = NO_ARTIFACTS;
else
artifacts = value;
artifacts = value == null || value.length == 0 ? NO_ARTIFACTS : value;
}

public void setCapabilities(IProvidedCapability[] newCapabilities) {
if (newCapabilities == null || newCapabilities.length == 0)
providedCapabilities = NO_PROVIDES;
else
providedCapabilities = newCapabilities;
providedCapabilities = newCapabilities == null || newCapabilities.length == 0 ? NO_PROVIDES : newCapabilities;
}

public void setFilter(IMatchExpression<IInstallableUnit> filter) {
Expand All @@ -276,14 +254,14 @@ public void setId(String id) {

public static IMatchExpression<IInstallableUnit> parseFilter(String filterStr) {
IFilterExpression filter = ExpressionUtil.parseLDAP(filterStr);
if (filter == null)
if (filter == null) {
return null;

}
synchronized (filterCache) {
IMatchExpression<IInstallableUnit> matchExpr = filterCache.get(filter);
if (matchExpr != null)
if (matchExpr != null) {
return matchExpr;

}
matchExpr = ExpressionUtil.getFactory().matchExpression(filterWrap, filter);
filterCache.put(filter, matchExpr);
return matchExpr;
Expand All @@ -294,16 +272,19 @@ public static IMatchExpression<IInstallableUnit> parseFilter(String filterStr) {
* Helper method to cache localized properties
*/
public String setLocalizedProperty(String key, String value) {
if (localizedProperties == null)
if (localizedProperties == null) {
localizedProperties = new OrderedProperties();
}
return localizedProperties.put(key, value);
}

public String setProperty(String key, String value) {
if (value == null)
if (value == null) {
return (properties != null ? (String) properties.remove(key) : null);
if (properties == null)
}
if (properties == null) {
properties = new OrderedProperties();
}
return (String) properties.setProperty(key, value);
}

Expand Down Expand Up @@ -396,37 +377,22 @@ public void setMetaRequiredCapabilities(IRequirement[] metaReqs) {

@Override
public Object getMember(String memberName) {
// It is OK to use identity comparisons here since
// a) All constant valued strings are always interned
// b) The Member constructor always interns the name
//
if (MEMBER_PROVIDED_CAPABILITIES == memberName)
return providedCapabilities;
if (MEMBER_ID == memberName)
return id;
if (MEMBER_VERSION == memberName)
return version;
if (MEMBER_PROPERTIES == memberName)
return properties;
if (MEMBER_FILTER == memberName)
return filter;
if (MEMBER_ARTIFACTS == memberName)
return artifacts;
if (MEMBER_REQUIREMENTS == memberName)
return requires;
if (MEMBER_LICENSES == memberName)
return licenses;
if (MEMBER_COPYRIGHT == memberName)
return copyright;
if (MEMBER_TOUCHPOINT_DATA == memberName)
return touchpointData;
if (MEMBER_TOUCHPOINT_TYPE == memberName)
return touchpointType;
if (MEMBER_UPDATE_DESCRIPTOR == memberName)
return updateInfo;
if (MEMBER_SINGLETON == memberName)
return Boolean.valueOf(singleton);
throw new IllegalArgumentException("No such member: " + memberName); //$NON-NLS-1$
return switch (memberName) {
case MEMBER_PROVIDED_CAPABILITIES -> providedCapabilities;
case MEMBER_ID -> id;
case MEMBER_VERSION -> version;
case MEMBER_PROPERTIES -> properties;
case MEMBER_FILTER -> filter;
case MEMBER_ARTIFACTS -> artifacts;
case MEMBER_REQUIREMENTS -> requires;
case MEMBER_LICENSES -> licenses;
case MEMBER_COPYRIGHT -> copyright;
case MEMBER_TOUCHPOINT_DATA -> touchpointData;
case MEMBER_TOUCHPOINT_TYPE -> touchpointType;
case MEMBER_UPDATE_DESCRIPTOR -> updateInfo;
case MEMBER_SINGLETON -> singleton;
default -> throw new IllegalArgumentException("No such member: " + memberName); //$NON-NLS-1$
};
}

public static IInstallableUnit contextIU(String ws, String os, String arch) {
Expand All @@ -441,8 +407,7 @@ public static IInstallableUnit contextIU(String ws, String os, String arch) {
public static IInstallableUnit contextIU(Map<String, String> environment) {
InstallableUnit ctxIU = new InstallableUnit();
ctxIU.setId("org.eclipse.equinox.p2.context.iu"); //$NON-NLS-1$
for (Map.Entry<String, String> entry : environment.entrySet())
ctxIU.setProperty(entry.getKey(), entry.getValue());
environment.forEach(ctxIU::setProperty);
return ctxIU;
}
}
Loading

0 comments on commit 67d4cd6

Please sign in to comment.