Skip to content

Commit

Permalink
Merge pull request #27340 from KyleAure/27098-concurrent-3.1-injection
Browse files Browse the repository at this point in the history
Concurrency 3.1 injection binding for qualifier and virtual
  • Loading branch information
KyleAure committed Jan 12, 2024
2 parents b4160bf + 23b61a0 commit 3493619
Show file tree
Hide file tree
Showing 9 changed files with 497 additions and 99 deletions.
48 changes: 27 additions & 21 deletions dev/io.openliberty.concurrent.internal/bnd.bnd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#*******************************************************************************
# Copyright (c) 2021, 2022 IBM Corporation and others.
# Copyright (c) 2021, 2024 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
# which accompanies this distribution, and is available at
Expand All @@ -24,6 +24,11 @@ Bundle-Description: Jakarta Concurrency 3.0+ implementation; version=${bVersion}

WS-TraceGroup: concurrent

Import-Package: \
jakarta.enterprise.concurrent; version="[3.0.0,4.0.0)", \
jakarta.enterprise.concurrent.spi; version="[3.0.0,4.0.0)", \
*

Export-Package: \
io.openliberty.concurrent.internal.messages

Expand All @@ -48,23 +53,24 @@ instrument.classesExcludes: io/openliberty/concurrent/internal/resources/*.class
io.openliberty.concurrent.internal.trigger.ZonedTriggerService

-buildpath: \
com.ibm.websphere.appserver.spi.kernel.service;version=latest,\
com.ibm.websphere.appserver.spi.logging;version=latest,\
com.ibm.websphere.org.osgi.core;version=latest,\
com.ibm.websphere.org.osgi.service.cm;version=latest,\
com.ibm.websphere.org.osgi.service.component;version=latest,\
com.ibm.wsspi.org.osgi.service.cm;version=latest,\
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest,\
com.ibm.wsspi.org.osgi.service.metatype;version=latest,\
com.ibm.ws.concurrency.policy;version=latest,\
com.ibm.ws.concurrent.jakarta;version=latest,\
com.ibm.ws.config;version=latest,\
com.ibm.ws.container.service;version=latest,\
com.ibm.ws.context;version=latest,\
com.ibm.ws.injection;version=latest,\
com.ibm.ws.javaee.dd.common;version=latest,\
com.ibm.ws.kernel.service;version=latest,\
com.ibm.ws.logging.core;version=latest,\
com.ibm.ws.resource;version=latest,\
com.ibm.ws.org.osgi.annotation.versioning;version=latest,\
io.openliberty.jakarta.concurrency.3.0;version=latest
com.ibm.websphere.appserver.spi.kernel.service;version=latest,\
com.ibm.websphere.appserver.spi.logging;version=latest,\
com.ibm.websphere.org.osgi.core;version=latest,\
com.ibm.websphere.org.osgi.service.cm;version=latest,\
com.ibm.websphere.org.osgi.service.component;version=latest,\
com.ibm.wsspi.org.osgi.service.cm;version=latest,\
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest,\
com.ibm.wsspi.org.osgi.service.metatype;version=latest,\
com.ibm.ws.concurrency.policy;version=latest,\
com.ibm.ws.concurrent.jakarta;version=latest,\
com.ibm.ws.config;version=latest,\
com.ibm.ws.container.service;version=latest,\
com.ibm.ws.context;version=latest,\
com.ibm.ws.injection;version=latest,\
com.ibm.ws.javaee.dd.common;version=latest,\
com.ibm.ws.javaee.version;version=latest,\
com.ibm.ws.kernel.service;version=latest,\
com.ibm.ws.logging.core;version=latest,\
com.ibm.ws.resource;version=latest,\
com.ibm.ws.org.osgi.annotation.versioning;version=latest,\
io.openliberty.jakarta.concurrency.3.1;version=latest
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2021,2022 IBM Corporation and others.
* Copyright (c) 2021, 2024 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0/
*
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
Expand Down Expand Up @@ -45,9 +45,16 @@ public class ContextServiceDefinitionBinding extends InjectionBinding<ContextSer
private static final String KEY_DESCRIPTION = "description";
private static final String KEY_PROPAGATED = "propagated";
private static final String KEY_UNCHANGED = "unchanged";
private static final String KEY_QUALIFIERS = "qualifiers";

private static final String[] DEFAULT_CLEARED = new String[] { ContextServiceDefinition.TRANSACTION };
private static final String[] DEFAULT_PROPAGATED = new String[] { ContextServiceDefinition.ALL_REMAINING };
private static final String[] DEFAULT_UNCHANGED = new String[] {};
private static final String[] DEFAULT_QUALIFIERS = new String[] {};

private final int eeVersion;

// Concurrent 3.0 attributes

private String[] cleared;
private boolean XMLcleared;
Expand All @@ -58,15 +65,23 @@ public class ContextServiceDefinitionBinding extends InjectionBinding<ContextSer
private String[] propagated;
private boolean XMLpropagated;

private Map<String, String> properties;
private final Set<String> XMLProperties = new HashSet<String>();

private String[] unchanged;
private boolean XMLunchanged;

public ContextServiceDefinitionBinding(String jndiName, ComponentNameSpaceConfiguration nameSpaceConfig) {
// Concurrent 3.1 attributes

private String[] qualifiers;
private boolean XMLqualifers;

// General attribute

private Map<String, String> properties;
private final Set<String> XMLProperties = new HashSet<String>();

public ContextServiceDefinitionBinding(String jndiName, ComponentNameSpaceConfiguration nameSpaceConfig, int eeVersion) {
super(null, nameSpaceConfig);
setJndiName(jndiName);
this.eeVersion = eeVersion;
}

@Override
Expand All @@ -83,10 +98,11 @@ protected JNDIEnvironmentRefType getJNDIEnvironmentRefType() {
public void merge(ContextServiceDefinition annotation, Class<?> instanceClass, Member member) throws InjectionException {
final boolean trace = TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled();
if (trace)
Tr.entry(this, tc, "merge", toString(annotation), instanceClass, member,
Tr.entry(this, tc, "merge", toString(annotation, eeVersion), instanceClass, member,
(XMLcleared ? " (xml)" : " ") + "cleared: " + toString(cleared) + " << " + toString(annotation.cleared()),
(XMLpropagated ? "(xml)" : " ") + "propagated: " + toString(propagated) + " << " + toString(annotation.propagated()),
(XMLunchanged ? " (xml)" : " ") + "unchanged: " + toString(unchanged) + " << " + toString(annotation.unchanged()));
(XMLunchanged ? " (xml)" : " ") + "unchanged: " + toString(unchanged) + " << " + toString(annotation.unchanged()),
(XMLqualifers ? " (xml)" : " ") + "qualifiers: " + toString(qualifiers) + " << " + (eeVersion >= 11 ? toString(annotation.qualifiers()) : "Unspecified"));

if (member != null) {
// ContextServiceDefinition is a class-level annotation only.
Expand All @@ -101,15 +117,20 @@ public void merge(ContextServiceDefinition annotation, Class<?> instanceClass, M
propagated = mergeAnnotationValue(propagated == DEFAULT_PROPAGATED ? null : propagated,
XMLpropagated, annotation.propagated(), KEY_PROPAGATED, DEFAULT_PROPAGATED);

properties = mergeAnnotationProperties(properties, XMLProperties, new String[] {}); // ContextServiceDefinition has no properties attribute
unchanged = mergeAnnotationValue(unchanged, XMLunchanged, annotation.unchanged(), KEY_UNCHANGED, DEFAULT_UNCHANGED);

unchanged = mergeAnnotationValue(unchanged, XMLunchanged, annotation.unchanged(), KEY_UNCHANGED, new String[0]);
//Only merge EE 11 annotations when present, otherwise rely on defaults from mergeXML
if (eeVersion >= 11)
qualifiers = mergeAnnotationValue(qualifiers, XMLqualifers, toQualifierStringArray(annotation.qualifiers()), KEY_QUALIFIERS, DEFAULT_QUALIFIERS);

properties = mergeAnnotationProperties(properties, XMLProperties, new String[] {}); // ContextServiceDefinition has no properties attribute

if (trace)
Tr.exit(this, tc, "merge", new String[] {
(XMLcleared ? " (xml)" : " ") + "cleared= " + toString(cleared),
(XMLpropagated ? "(xml)" : " ") + "propagated= " + toString(propagated),
(XMLunchanged ? " (xml)" : " ") + "unchanged= " + toString(unchanged)
(XMLunchanged ? " (xml)" : " ") + "unchanged= " + toString(unchanged),
(XMLqualifers ? " (xml)" : " ") + "qualifiers= " + toString(qualifiers)
});
}

Expand All @@ -119,7 +140,8 @@ void mergeXML(ContextService csd) throws InjectionConfigurationException {
Tr.entry(this, tc, "mergeXML", csd, csd.getName(),
(XMLcleared ? " (xml)" : " ") + "cleared: " + toString(cleared) + " << " + toString(csd.getCleared()),
(XMLpropagated ? "(xml)" : " ") + "propagated: " + toString(propagated) + " << " + toString(csd.getPropagated()),
(XMLunchanged ? " (xml)" : " ") + "unchanged: " + toString(unchanged) + " << " + toString(csd.getUnchanged()));
(XMLunchanged ? " (xml)" : " ") + "unchanged: " + toString(unchanged) + " << " + toString(csd.getUnchanged()),
(XMLqualifers ? " (xml)" : " ") + "qualifiers: " + toString(qualifiers) + " << " + toString(csd.getQualifiers()));

List<Description> descriptionList = csd.getDescriptions();

Expand All @@ -146,20 +168,36 @@ void mergeXML(ContextService csd) throws InjectionConfigurationException {
XMLpropagated = true;
}

List<Property> csdProps = csd.getProperties();
properties = mergeXMLProperties(properties, XMLProperties, csdProps);

String[] unchangedValues = csd.getUnchanged();
if (unchangedValues != null && unchangedValues.length > 0) {
unchanged = mergeXMLValue(unchanged, unchangedValues, "unchanged", KEY_UNCHANGED, null);
XMLunchanged |= true;
}

String[] qualifierValues = csd.getQualifiers();
if (qualifierValues == null || qualifierValues.length == 0) {
// No qualifiers provided via xml
if (qualifiers == null)
qualifiers = DEFAULT_QUALIFIERS;
} else if (qualifierValues.length == 1 && qualifierValues[0].isEmpty()) {
// Special case <qualifier></qualifier>
qualifiers = DEFAULT_QUALIFIERS;
XMLqualifers = true;
} else {
// List of qualifiers provided
qualifiers = mergeXMLValue(qualifiers, qualifierValues, "qualifier", KEY_QUALIFIERS, null);
XMLqualifers = true;
}

List<Property> csdProps = csd.getProperties();
properties = mergeXMLProperties(properties, XMLProperties, csdProps);

if (trace)
Tr.exit(this, tc, "mergeXML", new String[] {
(XMLcleared ? " (xml)" : " ") + "cleared= " + toString(cleared),
(XMLpropagated ? "(xml)" : " ") + "propagated= " + toString(propagated),
(XMLunchanged ? " (xml)" : " ") + "unchanged= " + toString(unchanged)
(XMLunchanged ? " (xml)" : " ") + "unchanged= " + toString(unchanged),
(XMLqualifers ? " (xml)" : " ") + "qualifiers= " + toString(qualifiers)
});
}

Expand All @@ -170,8 +208,10 @@ public void mergeSaved(InjectionBinding<ContextServiceDefinition> injectionBindi
mergeSavedValue(cleared, contextServiceBinding.cleared, "cleared");
mergeSavedValue(description, contextServiceBinding.description, "description");
mergeSavedValue(propagated, contextServiceBinding.propagated, "propagated");
mergeSavedValue(properties, contextServiceBinding.properties, "properties");
mergeSavedValue(unchanged, contextServiceBinding.unchanged, "unchanged");
mergeSavedValue(qualifiers, contextServiceBinding.qualifiers, "qualifier");
mergeSavedValue(properties, contextServiceBinding.properties, "properties");

}

void resolve() throws InjectionException {
Expand All @@ -186,29 +226,45 @@ void resolve() throws InjectionException {
addOrRemoveProperty(props, KEY_DESCRIPTION, description);
addOrRemoveProperty(props, KEY_PROPAGATED, propagated);
addOrRemoveProperty(props, KEY_UNCHANGED, unchanged);
addOrRemoveProperty(props, KEY_QUALIFIERS, qualifiers);

setObjects(null, createDefinitionReference(null, jakarta.enterprise.concurrent.ContextService.class.getName(), props));
}

@Trivial
static final String toString(ContextServiceDefinition anno) {
static final String toString(ContextServiceDefinition anno, int eeVersion) {
StringBuilder b = new StringBuilder();
b.append("ContextServiceDefinition@").append(Integer.toHexString(anno.hashCode())) //
b.append("ContextServiceDefinition@") //
.append(Integer.toHexString(anno.hashCode())) //
.append("#EE").append(eeVersion) //
.append("(name=").append(anno.name()) //
.append(", cleared=").append(Arrays.toString(anno.cleared())) //
.append(", propagated=").append(Arrays.toString(anno.propagated())) //
.append(", unchanged=").append(Arrays.toString(anno.unchanged())) //
.append(")");
.append(", unchanged=").append(Arrays.toString(anno.unchanged()));

if (eeVersion >= 11)
b.append(", qualifiers=").append(Arrays.toString(anno.qualifiers()));

b.append(")");
return b.toString();
}

@Trivial
private static final String toString(String[] list) {
private static final <T> String toString(T[] list) {
if (list == null || list.length == 0)
return "Unspecified";
boolean none = true;
for (int i = 0; none && i < list.length; i++)
none &= list[i] == null || list[i].length() == 0;
none &= list[i] == null || list[i].toString().isEmpty();
return none ? "None" : Arrays.toString(list);
}

@Trivial
private static final String[] toQualifierStringArray(Class<?>[] classList) {
String[] qualifierNames = new String[classList.length];
for (int i = 0; i < classList.length; i++) {
qualifierNames[i] = classList[i].getCanonicalName();
}
return qualifierNames;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2021,2022 IBM Corporation and others.
* Copyright (c) 2021, 2024 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0/
*
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
Expand All @@ -17,13 +17,17 @@
import java.util.Collections;
import java.util.List;

import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferencePolicyOption;

import com.ibm.websphere.ras.Tr;
import com.ibm.websphere.ras.TraceComponent;
import com.ibm.websphere.ras.annotation.Trivial;
import com.ibm.ws.javaee.dd.common.ContextService;
import com.ibm.ws.javaee.dd.common.JNDIEnvironmentRef;
import com.ibm.ws.javaee.version.JavaEEVersion;
import com.ibm.ws.kernel.service.util.SecureAction;
import com.ibm.wsspi.injectionengine.InjectionBinding;
import com.ibm.wsspi.injectionengine.InjectionException;
Expand All @@ -45,6 +49,11 @@ public class ContextServiceDefinitionProvider extends InjectionProcessorProvider
private static final List<Class<? extends JNDIEnvironmentRef>> REF_CLASSES = //
Collections.<Class<? extends JNDIEnvironmentRef>> singletonList(ContextService.class);

/**
* The Jakarta EE major version (ex. 10)
*/
private int eeVersion;

@Override
@Trivial
public Class<ContextServiceDefinition> getAnnotationClass() {
Expand All @@ -68,6 +77,16 @@ public InjectionProcessor<ContextServiceDefinition, ContextServiceDefinition.Lis
return new Processor();
}

/**
* The service ranking of JavaEEVersion ensures we get the highest
* Jakarta EE version for the configured features.
*/
@Reference(policyOption = ReferencePolicyOption.GREEDY)
protected void setEEVersion(ServiceReference<JavaEEVersion> ref) {
String version = (String) ref.getProperty("version");
eeVersion = Integer.parseInt(version.substring(0, version.indexOf('.')));
}

class Processor extends InjectionProcessor<ContextServiceDefinition, ContextServiceDefinition.List> {
@Trivial
public Processor() {
Expand All @@ -80,10 +99,10 @@ public InjectionBinding<ContextServiceDefinition> createInjectionBinding(Context
String jndiName) throws InjectionException {
final boolean trace = TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled();
if (trace)
Tr.entry(this, tc, "createInjectionBinding", ContextServiceDefinitionBinding.toString(annotation), instanceClass, member, jndiName);
Tr.entry(this, tc, "createInjectionBinding", ContextServiceDefinitionBinding.toString(annotation, eeVersion), instanceClass, member, jndiName);

InjectionBinding<ContextServiceDefinition> injectionBinding = //
new ContextServiceDefinitionBinding(jndiName, ivNameSpaceConfig);
new ContextServiceDefinitionBinding(jndiName, ivNameSpaceConfig, eeVersion);
injectionBinding.merge(annotation, instanceClass, null);

if (trace)
Expand Down Expand Up @@ -125,7 +144,7 @@ public void processXML() throws InjectionException {

ContextServiceDefinitionBinding binding;
if (injectionBinding == null) {
binding = new ContextServiceDefinitionBinding(jndiName, ivNameSpaceConfig);
binding = new ContextServiceDefinitionBinding(jndiName, ivNameSpaceConfig, eeVersion);
addInjectionBinding(binding);
} else {
binding = (ContextServiceDefinitionBinding) injectionBinding;
Expand Down
Loading

0 comments on commit 3493619

Please sign in to comment.