diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF index 8b6805915..e908340f6 100644 --- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF @@ -8,7 +8,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.tests.harness, org.eclipse.test.performance, - org.junit + org.junit, + org.eclipse.osgi.util;bundle-version="3.7.0";resolution:=optional Bundle-ActivationPolicy: lazy Import-Package: org.osgi.service.event; resolution:="optional" Export-Package: org.eclipse.osgi.tests.bundles, diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/appadmin/ApplicationAdminTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/appadmin/ApplicationAdminTest.java index 0eee66054..cdc78bfe4 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/appadmin/ApplicationAdminTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/appadmin/ApplicationAdminTest.java @@ -13,7 +13,11 @@ *******************************************************************************/ package org.eclipse.osgi.tests.appadmin; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.tests.session.ConfigurationSessionTestSuite; @@ -21,8 +25,16 @@ import org.eclipse.osgi.tests.OSGiTest; import org.eclipse.osgi.tests.OSGiTestsActivator; import org.eclipse.osgi.tests.bundles.BundleInstaller; -import org.osgi.framework.*; -import org.osgi.service.application.*; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.application.ApplicationDescriptor; +import org.osgi.service.application.ApplicationException; +import org.osgi.service.application.ApplicationHandle; +import org.osgi.service.application.ScheduledApplication; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; @@ -51,6 +63,12 @@ public static Test suite() { appAdminSessionTest.addBundle(PI_OSGI_SERVICES); appAdminSessionTest.addBundle(PI_OSGI_TESTS); appAdminSessionTest.setApplicationId(testRunnerApp); + appAdminSessionTest.addBundle("org.osgi.util.function"); + appAdminSessionTest.addBundle("org.osgi.util.measurement"); + appAdminSessionTest.addBundle("org.osgi.util.position"); + appAdminSessionTest.addBundle("org.osgi.util.promise"); + appAdminSessionTest.addBundle("org.osgi.util.xml"); + try { appAdminSessionTest.getSetup().setSystemProperty("eclipse.application.registerDescriptors", "true"); //$NON-NLS-1$//$NON-NLS-2$ } catch (SetupException e) { diff --git a/bundles/org.eclipse.osgi.util/.classpath b/bundles/org.eclipse.osgi.util/.classpath index aa36b63ce..dc7ce67ee 100644 --- a/bundles/org.eclipse.osgi.util/.classpath +++ b/bundles/org.eclipse.osgi.util/.classpath @@ -2,10 +2,4 @@ - - - - - - diff --git a/bundles/org.eclipse.osgi.util/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.util/META-INF/MANIFEST.MF index 9b5dfddfc..2725e321f 100644 --- a/bundles/org.eclipse.osgi.util/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi.util/META-INF/MANIFEST.MF @@ -2,23 +2,16 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %osgiUtil Bundle-SymbolicName: org.eclipse.osgi.util -Bundle-Version: 3.6.100.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Description: %osgiUtilDes Bundle-Vendor: %eclipse.org Bundle-Localization: plugin Bundle-DocUrl: http://www.eclipse.org Bundle-ContactAddress: www.eclipse.org -Export-Package: org.osgi.util.function;version="1.1", - org.osgi.util.measurement;version="1.0.2", - org.osgi.util.position;version="1.0.1";uses:="org.osgi.util.measurement", - org.osgi.util.promise;version="1.1.1";uses:="org.osgi.util.function", - org.osgi.util.xml;version="1.0.1";uses:="org.osgi.framework,javax.xml.parsers" -Import-Package: org.osgi.framework; version=1.1, - javax.xml.parsers, - org.osgi.util.function; version="[1.1, 1.2)", - org.osgi.util.measurement; version="[1.0.2, 1.1)", - org.osgi.util.position; version="[1.0.1, 1.1)", - org.osgi.util.promise; version="[1.1.1, 1.2)", - org.osgi.util.xml; version="[1.0.1, 1.1)" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Automatic-Module-Name: org.eclipse.osgi.util +Require-Bundle: org.osgi.util.function;bundle-version="[1.2.0,1.3.0)";visibility:=reexport, + org.osgi.util.promise;bundle-version="[1.2.0,1.3.0)";visibility:=reexport, + org.osgi.util.measurement;bundle-version="[1.0.0,1.1.0)";visibility:=reexport, + org.osgi.util.position;bundle-version="[1.0.0,1.1.0)";visibility:=reexport, + org.osgi.util.xml;bundle-version="[1.0.0,1.1.0)";visibility:=reexport diff --git a/bundles/org.eclipse.osgi.util/build.properties b/bundles/org.eclipse.osgi.util/build.properties index 4574bb9ff..b93aa9b29 100644 --- a/bundles/org.eclipse.osgi.util/build.properties +++ b/bundles/org.eclipse.osgi.util/build.properties @@ -14,11 +14,6 @@ bin.includes = plugin.properties,\ about.html,\ META-INF/,\ - .,\ about_files/ src.includes = about.html,\ about_files/ -source.. = src/ -output.. = bin/ -jars.extra.classpath = lib/osgi.annotation.jar,\ - lib/function.interface.jar diff --git a/bundles/org.eclipse.osgi.util/lib/function.interface.jar b/bundles/org.eclipse.osgi.util/lib/function.interface.jar deleted file mode 100755 index d2f08316f..000000000 Binary files a/bundles/org.eclipse.osgi.util/lib/function.interface.jar and /dev/null differ diff --git a/bundles/org.eclipse.osgi.util/lib/osgi.annotation.jar b/bundles/org.eclipse.osgi.util/lib/osgi.annotation.jar deleted file mode 100644 index dda27d2fe..000000000 Binary files a/bundles/org.eclipse.osgi.util/lib/osgi.annotation.jar and /dev/null differ diff --git a/bundles/org.eclipse.osgi.util/pom.xml b/bundles/org.eclipse.osgi.util/pom.xml index 571aef445..5841e99be 100644 --- a/bundles/org.eclipse.osgi.util/pom.xml +++ b/bundles/org.eclipse.osgi.util/pom.xml @@ -19,7 +19,7 @@ org.eclipse.osgi org.eclipse.osgi.util - 3.6.100-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Consumer.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Consumer.java deleted file mode 100644 index 3636c6043..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Consumer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2017). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.function; - -import org.osgi.annotation.versioning.ConsumerType; - -/** - * A function that accepts a single argument and produces no result. - *

- * This is a functional interface and can be used as the assignment target for a - * lambda expression or method reference. - * - * @param The type of the function input. - * @ThreadSafe - * @since 1.1 - * @author $Id$ - */ -@ConsumerType -@FunctionalInterface -public interface Consumer { - /** - * Applies this function to the specified argument. - * - * @param t The input to this function. - * @throws Exception An exception thrown by the method. - */ - void accept(T t) throws Exception; -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Function.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Function.java deleted file mode 100644 index 3d17c97c7..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Function.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.function; - -import org.osgi.annotation.versioning.ConsumerType; - -/** - * A function that accepts a single argument and produces a result. - * - *

- * This is a functional interface and can be used as the assignment target for a - * lambda expression or method reference. - * - * @param The type of the function input. - * @param The type of the function output. - * - * @ThreadSafe - * @author $Id$ - */ -@ConsumerType -@FunctionalInterface -public interface Function { - /** - * Applies this function to the specified argument. - * - * @param t The input to this function. - * @return The output of this function. - * @throws Exception An exception thrown by the method. - */ - R apply(T t) throws Exception; -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Predicate.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Predicate.java deleted file mode 100644 index 681b771c2..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/Predicate.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.function; - -import org.osgi.annotation.versioning.ConsumerType; - -/** - * A predicate that accepts a single argument and produces a boolean result. - * - *

- * This is a functional interface and can be used as the assignment target for a - * lambda expression or method reference. - * - * @param The type of the predicate input. - * - * @ThreadSafe - * @author $Id$ - */ -@ConsumerType -@FunctionalInterface -public interface Predicate { - /** - * Evaluates this predicate on the specified argument. - * - * @param t The input to this predicate. - * @return {@code true} if the specified argument is accepted by this - * predicate; {@code false} otherwise. - * @throws Exception An exception thrown by the method. - */ - boolean test(T t) throws Exception; -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/package-info.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/package-info.java deleted file mode 100644 index 82ed82dc4..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/function/package-info.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Function Package Version 1.1. - *

- * Bundles wishing to use this package must list the package in the - * Import-Package header of the bundle's manifest. - *

- * Example import for consumers using the API in this package: - *

- * {@code Import-Package: org.osgi.util.function; version="[1.1,2.0)"} - *

- * Example import for providers implementing the API in this package: - *

- * {@code Import-Package: org.osgi.util.function; version="[1.1,1.2)"} - * - * @author $Id$ - */ - -@Version("1.1") -package org.osgi.util.function; - -import org.osgi.annotation.versioning.Version; - diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/Measurement.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/Measurement.java deleted file mode 100644 index 4a8cf6629..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/Measurement.java +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2002, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.measurement; - -/** - * Represents a value with an error, a unit and a time-stamp. - * - *

- * A {@code Measurement} object is used for maintaining the tuple of value, - * error, unit and time-stamp. The value and error are represented as doubles - * and the time is measured in milliseconds since midnight, January 1, 1970 UTC. - * - *

- * Mathematic methods are provided that correctly calculate taking the error - * into account. A runtime error will occur when two measurements are used in an - * incompatible way. E.g., when a speed (m/s) is added to a distance (m). The - * measurement class will correctly track changes in unit during multiplication - * and division, always coercing the result to the most simple form. See - * {@link Unit} for more information on the supported units. - * - *

- * Errors in the measurement class are absolute errors. Measurement errors - * should use the P95 rule. Actual values must fall in the range value +/- error - * 95% or more of the time. - * - *

- * A {@code Measurement} object is immutable in order to be easily shared. - * - *

- * Note: This class has a natural ordering that is inconsistent with equals. See - * {@link #compareTo(Object)}. - * - * @Immutable - * @author $Id$ - */ -public class Measurement implements Comparable { - private final double value; - private final double error; - private final long time; - private final Unit unit; - private transient String name; - private transient int hashCode; - - /** - * Create a new {@code Measurement} object. - * - * @param value The value of the {@code Measurement}. - * @param error The error of the {@code Measurement}. - * @param unit The {@code Unit} object in which the value is measured. If - * this argument is {@code null}, then the unit will be set to - * {@link Unit#unity}. - * @param time The time measured in milliseconds since midnight, January 1, - * 1970 UTC. - */ - public Measurement(double value, double error, Unit unit, long time) { - this.value = value; - this.error = Math.abs(error); - this.unit = (unit != null) ? unit : Unit.unity; - this.time = time; - name = null; - hashCode = 0; - } - - /** - * Create a new {@code Measurement} object with a time of zero. - * - * @param value The value of the {@code Measurement}. - * @param error The error of the {@code Measurement}. - * @param unit The {@code Unit} object in which the value is measured. If - * this argument is {@code null}, then the unit will be set to - * {@link Unit#unity}. - */ - public Measurement(double value, double error, Unit unit) { - this(value, error, unit, 0l); - } - - /** - * Create a new {@code Measurement} object with an error of 0.0 and a time - * of zero. - * - * @param value The value of the {@code Measurement}. - * @param unit The {@code Unit} in which the value is measured. If this - * argument is {@code null}, then the unit will be set to - * {@link Unit#unity}. - */ - public Measurement(double value, Unit unit) { - this(value, 0.0d, unit, 0l); - } - - /** - * Create a new {@code Measurement} object with an error of 0.0, a unit of - * {@link Unit#unity} and a time of zero. - * - * @param value The value of the {@code Measurement}. - */ - public Measurement(double value) { - this(value, 0.0d, null, 0l); - } - - /** - * Returns the value of this {@code Measurement} object. - * - * @return The value of this {@code Measurement} object as a double. - */ - public final double getValue() { - return value; - } - - /** - * Returns the error of this {@code Measurement} object. The error is always - * a positive value. - * - * @return The error of this {@code Measurement} as a double. - */ - public final double getError() { - return error; - } - - /** - * Returns the {@code Unit} object of this {@code Measurement} object. - * - * @return The {@code Unit} object of this {@code Measurement} object. - * - * @see Unit - */ - public final Unit getUnit() { - return unit; - } - - /** - * Returns the time at which this {@code Measurement} object was taken. The - * time is measured in milliseconds since midnight, January 1, 1970 UTC, or - * zero when not defined. - * - * @return The time at which this {@code Measurement} object was taken or - * zero. - */ - public final long getTime() { - return time; - } - - /** - * Returns a new {@code Measurement} object that is the product of this - * object multiplied by the specified object. - * - * @param m The {@code Measurement} object that will be multiplied with this - * object. - * @return A new {@code Measurement} that is the product of this object - * multiplied by the specified object. The error and unit of the new - * object are computed. The time of the new object is set to the - * time of this object. - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified object cannot be multiplied. - * @see Unit - */ - public Measurement mul(Measurement m) { - double mvalue = m.value; - return new Measurement(value * mvalue, Math.abs(value) * m.error + error * Math.abs(mvalue), unit.mul(m.unit), time); - } - - /** - * Returns a new {@code Measurement} object that is the product of this - * object multiplied by the specified value. - * - * @param d The value that will be multiplied with this object. - * @param u The {@code Unit} of the specified value. - * @return A new {@code Measurement} object that is the product of this - * object multiplied by the specified value. The error and unit of - * the new object are computed. The time of the new object is set to - * the time of this object. - * @throws ArithmeticException If the units of this object and the specified - * value cannot be multiplied. - * @see Unit - */ - public Measurement mul(double d, Unit u) { - return new Measurement(value * d, error * Math.abs(d), unit.mul(u), time); - } - - /** - * Returns a new {@code Measurement} object that is the product of this - * object multiplied by the specified value. - * - * @param d The value that will be multiplied with this object. - * @return A new {@code Measurement} object that is the product of this - * object multiplied by the specified value. The error of the new - * object is computed. The unit and time of the new object is set to - * the unit and time of this object. - */ - public Measurement mul(double d) { - return new Measurement(value * d, error * Math.abs(d), unit, time); - } - - /** - * Returns a new {@code Measurement} object that is the quotient of this - * object divided by the specified object. - * - * @param m The {@code Measurement} object that will be the divisor of this - * object. - * @return A new {@code Measurement} object that is the quotient of this - * object divided by the specified object. The error and unit of the - * new object are computed. The time of the new object is set to the - * time of this object. - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified object cannot be divided. - * @see Unit - */ - public Measurement div(Measurement m) { - double mvalue = m.value; - return new Measurement(value / mvalue, (Math.abs(value) * m.error + error * Math.abs(mvalue)) / (mvalue * mvalue), unit.div(m.unit), time); - } - - /** - * Returns a new {@code Measurement} object that is the quotient of this - * object divided by the specified value. - * - * @param d The value that will be the divisor of this object. - * @param u The {@code Unit} object of the specified value. - * @return A new {@code Measurement} that is the quotient of this object - * divided by the specified value. The error and unit of the new - * object are computed. The time of the new object is set to the - * time of this object. - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified object cannot be divided. - * @see Unit - */ - public Measurement div(double d, Unit u) { - return new Measurement(value / d, error / Math.abs(d), unit.div(u), time); - } - - /** - * Returns a new {@code Measurement} object that is the quotient of this - * object divided by the specified value. - * - * @param d The value that will be the divisor of this object. - * @return A new {@code Measurement} object that is the quotient of this - * object divided by the specified value. The error of the new - * object is computed. The unit and time of the new object is set to - * the {@code Unit} and time of this object. - */ - public Measurement div(double d) { - return new Measurement(value / d, error / Math.abs(d), unit, time); - } - - /** - * Returns a new {@code Measurement} object that is the sum of this object - * added to the specified object. - * - * The error and unit of the new object are computed. The time of the new - * object is set to the time of this object. - * - * @param m The {@code Measurement} object that will be added with this - * object. - * @return A new {@code Measurement} object that is the sum of this and m. - * @see Unit - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified object cannot be added. - */ - public Measurement add(Measurement m) { - return new Measurement(value + m.value, error + m.error, unit.add(m.unit), time); - } - - /** - * Returns a new {@code Measurement} object that is the sum of this object - * added to the specified value. - * - * @param d The value that will be added with this object. - * @param u The {@code Unit} object of the specified value. - * @return A new {@code Measurement} object that is the sum of this object - * added to the specified value. The unit of the new object is - * computed. The error and time of the new object is set to the - * error and time of this object. - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified value cannot be added. - * @see Unit - */ - public Measurement add(double d, Unit u) { - return new Measurement(value + d, error, unit.add(u), time); - } - - /** - * Returns a new {@code Measurement} object that is the sum of this object - * added to the specified value. - * - * @param d The value that will be added with this object. - * @return A new {@code Measurement} object that is the sum of this object - * added to the specified value. The error, unit, and time of the - * new object is set to the error, {@code Unit} and time of this - * object. - */ - public Measurement add(double d) { - return new Measurement(value + d, error, unit, time); - } - - /** - * Returns a new {@code Measurement} object that is the subtraction of the - * specified object from this object. - * - * @param m The {@code Measurement} object that will be subtracted from this - * object. - * @return A new {@code Measurement} object that is the subtraction of the - * specified object from this object. The error and unit of the new - * object are computed. The time of the new object is set to the - * time of this object. - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified object cannot be subtracted. - * @see Unit - */ - public Measurement sub(Measurement m) { - return new Measurement(value - m.value, error + m.error, unit.sub(m.unit), time); - } - - /** - * Returns a new {@code Measurement} object that is the subtraction of the - * specified value from this object. - * - * @param d The value that will be subtracted from this object. - * @param u The {@code Unit} object of the specified value. - * @return A new {@code Measurement} object that is the subtraction of the - * specified value from this object. The unit of the new object is - * computed. The error and time of the new object is set to the - * error and time of this object. - * @throws ArithmeticException If the {@code Unit} objects of this object - * and the specified object cannot be subtracted. - * @see Unit - */ - public Measurement sub(double d, Unit u) { - return new Measurement(value - d, error, unit.sub(u), time); - } - - /** - * Returns a new {@code Measurement} object that is the subtraction of the - * specified value from this object. - * - * @param d The value that will be subtracted from this object. - * @return A new {@code Measurement} object that is the subtraction of the - * specified value from this object. The error, unit and time of the - * new object is set to the error, {@code Unit} object and time of - * this object. - */ - public Measurement sub(double d) { - return new Measurement(value - d, error, unit, time); - } - - /** - * Returns a {@code String} object representing this {@code Measurement} - * object. - * - * @return a {@code String} object representing this {@code Measurement} - * object. - */ - @Override - public String toString() { - String result = name; - if (result == null) { - StringBuilder sb = new StringBuilder(); - sb.append(value); - if (error != 0.0d) { - sb.append(" +/- "); - sb.append(error); - } - String u = unit.toString(); - if (u.length() > 0) { - sb.append(" "); - sb.append(u); - } - result = sb.toString(); - name = result; - } - return result; - } - - /** - * Compares this object with the specified object for order. Returns a - * negative integer, zero, or a positive integer if this object is less - * than, equal to, or greater than the specified object. - * - *

- * Note: This class has a natural ordering that is inconsistent with equals. - * For this method, another {@code Measurement} object is considered equal - * if there is some {@code x} such that - * - *

-	 * getValue() - getError() <= x <= getValue() + getError()
-	 * 
- * - * for both {@code Measurement} objects being compared. - * - * @param obj The object to be compared. - * @return A negative integer, zero, or a positive integer if this object is - * less than, equal to, or greater than the specified object. - * - * @throws ClassCastException If the specified object is not of type - * {@code Measurement}. - * @throws ArithmeticException If the unit of the specified - * {@code Measurement} object is not equal to the {@code Unit} - * object of this object. - */ - @Override - public int compareTo(Object obj) { - if (this == obj) { - return 0; - } - Measurement that = (Measurement) obj; - if (!unit.equals(that.unit)) { - throw new ArithmeticException("Cannot compare " + this + " and " + that); - } - int result = Double.compare(value, that.value); - if (result == 0) { - return 0; - } - if (result < 0) { - if (Double.compare(value + error, that.value - that.error) >= 0) { - return 0; - } - return -1; - } - if (Double.compare(value - error, that.value + that.error) <= 0) { - return 0; - } - return 1; - } - - /** - * Returns a hash code value for this object. - * - * @return A hash code value for this object. - */ - @Override - public int hashCode() { - int h = hashCode; - if (h == 0) { - long bits = Double.doubleToLongBits(value); - h = 31 * 17 + ((int) (bits ^ (bits >>> 32))); - bits = Double.doubleToLongBits(error); - h = 31 * h + ((int) (bits ^ (bits >>> 32))); - h = 31 * h + unit.hashCode(); - hashCode = h; - } - return h; - } - - /** - * Returns whether the specified object is equal to this object. Two - * {@code Measurement} objects are equal if they have same value, error and - * {@code Unit}. - * - *

- * Note: This class has a natural ordering that is inconsistent with equals. - * See {@link #compareTo(Object)}. - * - * @param obj The object to compare with this object. - * @return {@code true} if this object is equal to the specified object; - * {@code false} otherwise. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof Measurement)) { - return false; - } - Measurement that = (Measurement) obj; - return (Double.compare(value, that.value) == 0) && (Double.compare(error, that.error) == 0) && unit.equals(that.unit); - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/State.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/State.java deleted file mode 100644 index e9fcca59e..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/State.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2002, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.measurement; - -/** - * Groups a state name, value and timestamp. - * - *

- * The state itself is represented as an integer and the time is measured in - * milliseconds since midnight, January 1, 1970 UTC. - * - *

- * A {@code State} object is immutable so that it may be easily shared. - * - * @Immutable - * @author $Id$ - */ -public class State { - private final int value; - private final long time; - private final String name; - - /** - * Create a new {@code State} object. - * - * @param value The value of the state. - * @param name The name of the state. - * @param time The time measured in milliseconds since midnight, January 1, - * 1970 UTC. - */ - public State(int value, String name, long time) { - this.value = value; - this.name = name; - this.time = time; - } - - /** - * Create a new {@code State} object with a time of 0. - * - * @param value The value of the state. - * @param name The name of the state. - */ - public State(int value, String name) { - this(value, name, 0); - } - - /** - * Returns the value of this {@code State}. - * - * @return The value of this {@code State} object. - */ - public final int getValue() { - return value; - } - - /** - * Returns the time with which this {@code State} was created. - * - * @return The time with which this {@code State} was created. The time is - * measured in milliseconds since midnight, January 1, 1970 UTC. - */ - public final long getTime() { - return time; - } - - /** - * Returns the name of this {@code State}. - * - * @return The name of this {@code State} object. - */ - public final String getName() { - return name; - } - - /** - * Returns a {@code String} object representing this object. - * - * @return a {@code String} object representing this object. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(value); - if (name != null) { - sb.append(" \""); - sb.append(name); - sb.append("\""); - } - return sb.toString(); - } - - /** - * Returns a hash code value for this object. - * - * @return A hash code value for this object. - */ - @Override - public int hashCode() { - int hash = 31 * 17 + value; - if (name != null) { - hash = 31 * hash + name.hashCode(); - } - return hash; - } - - /** - * Return whether the specified object is equal to this object. Two - * {@code State} objects are equal if they have same value and name. - * - * @param obj The object to compare with this object. - * @return {@code true} if this object is equal to the specified object; - * {@code false} otherwise. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof State)) { - return false; - } - State that = (State) obj; - if (value != that.value) { - return false; - } - if (name == that.name) { - return true; - } - if (name == null) { - return false; - } - return name.equals(that.name); - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/Unit.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/Unit.java deleted file mode 100644 index 64d749c23..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/Unit.java +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2002, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.measurement; - -import java.util.HashMap; -import java.util.Map; - -/** - * A unit system for measurements. - * - * This class contains definitions of the most common SI units. - *

- * - *

- * This class only support exponents for the base SI units in the range -64 to - * +63. Any operation which produces an exponent outside of this range will - * result in a {@code Unit} object with undefined exponents. - * - * @Immutable - * @author $Id$ - */ -/* - * This local class maintains the information about units. It can calculate new - * units when two values are multiplied, divided, added or subtracted.

The - * unit works with the 7 basic SI types + rad + up to 2^6 custom types. For each - * type, the unit keeps a bit mask with the exponents of the basic types. Eg. - * m/s is m = 1, s = -1. Multiplying one unit with another means that the bit - * masks are added, dividing means that the bit masks are subtracted.

This - * class can handle any reasonable combination of SI units. However, it will - * always try to coerce results back into the basic set. E.g. when you do V*A - * you should get W and not m2.kg/s3 . Only when the existing types do not match - * does the unit fallback to the expanded form.

This class uses offset - * arithmetic. This means that the exponents are stored in an long. The special - * field is used for units that should not be arithmetically divided or - * multiplied, like longitude and lattitude. These special units can however, be - * divided and multiplied by the basic 7 constants of the SI, e.g. deg/s. - */ -public class Unit { - private final static long UNITY = createType(0, 0, 0, 0, 0, 0, 0, 0, 0); - private final static long ZERO = 0x40L; - private final static long MASK = 0x7fL; - private final static int m_SHIFT = 0; - private final static int s_SHIFT = 7; - private final static int kg_SHIFT = 14; - private final static int K_SHIFT = 21; - private final static int A_SHIFT = 28; - private final static int mol_SHIFT = 35; - private final static int cd_SHIFT = 42; - private final static int rad_SHIFT = 49; - private final static int x_SHIFT = 56; - private final static long x_MASK = MASK << x_SHIFT; - /** No Unit (Unity) */ - public final static Unit unity = new Unit("", UNITY); // Unity - /* SI Base Units */ - /** The length unit meter (m) */ - public final static Unit m = new Unit("m", createType(0, 0, 0, 0, 0, 0, 0, 0, 1)); // Distance - // meter - /** The time unit second (s) */ - public final static Unit s = new Unit("s", createType(0, 0, 0, 0, 0, 0, 0, 1, 0)); // Time - // Seconds - // s - /** The mass unit kilogram (kg) */ - public final static Unit kg = new Unit("kg", createType(0, 0, 0, 0, 0, 0, 1, 0, 0)); // Mass - // kilogram - // kg - /** The temperature unit kelvin (K) */ - public final static Unit K = new Unit("K", createType(0, 0, 0, 0, 0, 1, 0, 0, 0)); // Temperature - // kelvin - // K - /** The electric current unit ampere (A) */ - public final static Unit A = new Unit("A", createType(0, 0, 0, 0, 1, 0, 0, 0, 0)); // Current - // ampere - // A - /** The amount of substance unit mole (mol) */ - public final static Unit mol = new Unit("mol", createType(0, 0, 0, 1, 0, 0, 0, 0, 0)); // Substance - // mole - // mol - /** The luminous intensity unit candela (cd) */ - public final static Unit cd = new Unit("cd", createType(0, 0, 1, 0, 0, 0, 0, 0, 0)); // Light - // candela - // cd - /* SI Derived Units */ - /** The speed unit meter per second (m/s) */ - public final static Unit m_s = new Unit("m/s", createType(0, 0, 0, 0, 0, 0, 0, -1, 1)); // Speed - // m/s - /** The acceleration unit meter per second squared (m/s2) */ - public final static Unit m_s2 = new Unit("m/s2", createType(0, 0, 0, 0, 0, 0, 0, -2, 1)); // Acceleration - // m/s^2 - /** The area unit square meter (m2) */ - public final static Unit m2 = new Unit("m2", createType(0, 0, 0, 0, 0, 0, 0, 0, 2)); // Surface - // m^2 - /** The volume unit cubic meter (m3) */ - public final static Unit m3 = new Unit("m3", createType(0, 0, 0, 0, 0, 0, 0, 0, 3)); // Volume - // m^3 - /** - * The frequency unit hertz (Hz). - *

- * hertz is expressed in SI units as 1/s - */ - public final static Unit Hz = new Unit("Hz", createType(0, 0, 0, 0, 0, 0, 0, -1, 0)); // Frequency - // 1/s - /** - * The force unit newton (N). - *

- * N is expressed in SI units as m·kg/s2 - */ - public final static Unit N = new Unit("N", createType(0, 0, 0, 0, 0, 0, 1, -2, 1)); // Force - // newton - // (m*kg)/s^2 - /** - * The pressure unit pascal (Pa). - *

- * Pa is equal to N/m2 or is expressed in SI units as - * kg/m·s2 - */ - public final static Unit Pa = new Unit("Pa", createType(0, 0, 0, 0, 0, 0, 1, -2, -1)); // Pressure - // pascal - // kg/(m*s^2) - /** - * The energy unit joule (J). - *

- * joule is equal to N·m or is expressed in SI units as - * m2·kg/s2 - */ - public final static Unit J = new Unit("J", createType(0, 0, 0, 0, 0, 0, 1, -2, 2)); // Energy - // joule - // (m^2*kg)/s^2 - /** - * The power unit watt (W). - *

- * watt is equal to J/s or is expressed in SI units as - * m2·kg/s3 - */ - public final static Unit W = new Unit("W", createType(0, 0, 0, 0, 0, 0, 1, -3, 2)); // Power - // watt - // (m^2*kg)/s^3 - /** - * The electric charge unit coulomb (C). - *

- * coulomb is expressed in SI units as s·A - */ - public final static Unit C = new Unit("C", createType(0, 0, 0, 0, 1, 0, 0, 1, 0)); // Charge - // coulumb - // s*A - /** - * The electric potential difference unit volt (V). - *

- * volt is equal to W/A or is expressed in SI units as - * m2·kg/s3·A - */ - public final static Unit V = new Unit("V", createType(0, 0, 0, 0, -1, 0, 1, -3, 2)); // El. - // Potent. - // volt - // (m^2*kg)/(s^3*A) - /** - * The capacitance unit farad (F). - *

- * farad is equal to C/V or is expressed in SI units as - * s4·A2/m2·kg - */ - public final static Unit F = new Unit("F", createType(0, 0, 0, 0, 2, 0, -1, 4, -2)); // Capacitance - // farad - // (s^4*A^2)/(m^2*kg) - /** - * The electric resistance unit ohm. - *

- * ohm is equal to V/A or is expressed in SI units as - * m2·kg/s3·A2 - */ - public final static Unit Ohm = new Unit("Ohm", createType(0, 0, 0, 0, -2, 0, 1, -3, 2)); // Resistance - // ohm - // (m^2*kg)/(s^3*A^2) - /** - * The electric conductance unit siemens (S). - *

- * siemens is equal to A/V or is expressed in SI units as - * s3·A2/m2·kg - */ - public final static Unit S = new Unit("S", createType(0, 0, 0, 0, 2, 0, -1, 3, -2)); // Conductance - // siemens - // (s^3*A^2)/(m^2*kg) - /** - * The magnetic flux unit weber (Wb). - *

- * weber is equal to V·s or is expressed in SI units as - * m2·kg/s2·A - */ - public final static Unit Wb = new Unit("Wb", createType(0, 0, 0, 0, -1, 0, 1, -2, 2)); // Magn. - // Flux - // weber - // (m^2*kg)/(s^2*A) - /** - * The magnetic flux density unit tesla (T). - *

- * tesla is equal to Wb/m2 or is expressed in SI units as - * kg/s2·A - */ - public final static Unit T = new Unit("T", createType(0, 0, 0, 0, -1, 0, 1, -2, 0)); // Magn. - // Flux - // Dens. - // tesla - // kg/(s^2*A) - /** - * The illuminance unit lux (lx). - *

- * lux is expressed in SI units as cd/m2 - */ - public final static Unit lx = new Unit("lx", createType(0, 0, 1, 0, 0, 0, 0, 0, -2)); // Illuminace - // lux - // cd/m^2 - /** - * The absorbed dose unit gray (Gy). - *

- * Gy is equal to J/kg or is expressed in SI units as - * m2/s2 - */ - public final static Unit Gy = new Unit("Gy", createType(0, 0, 0, 0, 0, 0, 0, -2, 2)); // Absorbed - // dose - // gray - // m^2/s^2 - /** - * The catalytic activity unit katal (kat). - *

- * katal is expressed in SI units as mol/s - */ - public final static Unit kat = new Unit("kat", createType(0, 0, 0, 1, 0, 0, 0, -1, 0)); // Catalytic - // Act. - // katal - // mol/s - /** The angle unit radians (rad) */ - public final static Unit rad = new Unit("rad", createType(0, 1, 0, 0, 0, 0, 0, 0, 0)); // Angle - // radians - // rad - /** - * An array containing all units defined. The first seven items must be m, - * s, kg, K, A, mol, cd, rad in this order! - */ - private final static Unit[] allUnits = new Unit[] {m, s, kg, K, A, mol, cd, rad, m_s, m_s2, m2, m3, Hz, N, Pa, J, W, C, V, F, Ohm, S, Wb, T, lx, Gy, kat, unity}; - - /* @GuardedBy("Unit.class") */ - private static Map base; - private final String name; - private final long type; - - /** - * Creates a new {@code Unit} instance. - * - * @param name the name of the {@code Unit} - * @param type the type of the {@code Unit} - */ - private Unit(String name, long type) { - if (name == null) { - name = computeName(type); - } - this.name = name; - this.type = type; - // System.out.println( name + " " + Long.toHexString( type ) ); - } - - /** - * Create a type field from the base SI unit exponent values. - * - */ - private static long createType(int _x, int _rad, int _cd, int _mol, int _A, int _K, int _kg, int _s, int _m) { - return (((ZERO + _m) & MASK) << m_SHIFT) | (((ZERO + _s) & MASK) << s_SHIFT) | (((ZERO + _kg) & MASK) << kg_SHIFT) | (((ZERO + _K) & MASK) << K_SHIFT) | (((ZERO + _A) & MASK) << A_SHIFT) - | (((ZERO + _mol) & MASK) << mol_SHIFT) | (((ZERO + _cd) & MASK) << cd_SHIFT) | (((ZERO + _rad) & MASK) << rad_SHIFT) | (((long) _x) << x_SHIFT); - } - - /** - * Checks whether this {@code Unit} object is equal to the specified - * {@code Unit} object. The {@code Unit} objects are considered equal if - * their exponents are equal. - * - * @param obj the {@code Unit} object that should be checked for equality - * - * @return true if the specified {@code Unit} object is equal to this - * {@code Unit} object. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof Unit)) { - return false; - } - return ((Unit) obj).type == type; - } - - /** - * Returns the hash code for this object. - * - * @return This object's hash code. - */ - @Override - public int hashCode() { - return 31 * 17 + (int) (type ^ (type >>> 32)); - } - - /** - * Returns a new {@code Unit} that is the multiplication of this - * {@code Unit} and the {@code Unit} specified - * - * @param that the {@code Unit} that will be multiplied with this - * {@code Unit} - * - * @return a new {@code Unit} that is the multiplication of this - * {@code Unit} and the {@code Unit} specified - * - * @throws RuntimeException if both {@code Unit} s are special - * - * @see Unit#isSpecial() - */ - Unit mul(Unit that) { - if (this.isSpecial() && that.isSpecial()) { - throw new ArithmeticException("Cannot multiply " + this + " with " + that); - } - return find(this.type - UNITY + that.type); - } - - /** - * Returns a new {@code Unit} that is the division of this {@code Unit} and - * the {@code Unit} specified - * - * @param that the {@code Unit} that this {@code Unit} will be divided with - * @return a new {@code Unit} that is the division of this {@code Unit} and - * the {@code Unit} specified - * - * @throws RuntimeException if both {@code Unit} s are special - * - * @see Unit#isSpecial() - */ - Unit div(Unit that) { - if (this.isSpecial() && that.isSpecial()) { - if (this.type == that.type) { - return Unit.unity; - } - throw new ArithmeticException("Cannot divide " + this + " by " + that); - } - return find(this.type - that.type + UNITY); - } - - /** - * Returns a new {@code Unit} that is the addition of this {@code Unit} and - * the {@code Unit} specified. - * - * @param that the {@code Unit} that should be added to this {@code Unit} - * - * @return a new {@code Unit} that is the addition of this {@code Unit} and - * the {@code Unit} specified. - * - * @throws RuntimeException if the two {@code Unit} s are not the same - */ - Unit add(Unit that) { - if (!this.equals(that)) { - throw new ArithmeticException("Cannot add " + this + " to " + that); - } - return this; - } - - /** - * Returns a new {@code Unit} that is the subtraction between this - * {@code Unit} and the {@code Unit} specified. - * - * @param that the {@code Unit} that will be subtracted from this - * {@code Unit} - * @return a new {@code Unit} that is the subtraction between this - * {@code Unit} and the {@code Unit} specified. - * - * @throws RuntimeException if the {@code Unit} specified is not the same as - * this {@code Unit} - */ - Unit sub(Unit that) { - if (!this.equals(that)) { - throw new ArithmeticException("Cannot subtract " + that + " from " + this); - } - return this; - } - - /** - * Finds a {@code Unit} based on a type. If the {@code Unit} is not found, - * it will be created and added to the list of all units under a null name. - * - * @param type the type of the {@code Unit} to find - * - * @return the {@code Unit} - */ - static synchronized Unit find(long type) { - if (base == null) { - int size = allUnits.length; - base = new HashMap<>(size << 1); - for (int i = 0; i < size; i++) { - base.put(allUnits[i], allUnits[i]); - } - } - Unit unit = new Unit(null, type); - Unit out = base.get(unit); - if (out == null) { - base.put(unit, unit); - out = unit; - } - return out; - } - - /** - * Returns a {@code String} object representing the {@code Unit} - * - * @return A {@code String} object representing the {@code Unit} - */ - @Override - public String toString() { - return name; - } - - private static String computeName(long type) { - int _m = (int) (((type >> m_SHIFT) & MASK) - ZERO); - int _s = (int) (((type >> s_SHIFT) & MASK) - ZERO); - int _kg = (int) (((type >> kg_SHIFT) & MASK) - ZERO); - int _K = (int) (((type >> K_SHIFT) & MASK) - ZERO); - int _A = (int) (((type >> A_SHIFT) & MASK) - ZERO); - int _mol = (int) (((type >> mol_SHIFT) & MASK) - ZERO); - int _cd = (int) (((type >> cd_SHIFT) & MASK) - ZERO); - int _rad = (int) (((type >> rad_SHIFT) & MASK) - ZERO); - StringBuilder numerator = new StringBuilder(); - StringBuilder denominator = new StringBuilder(); - addSIname(_m, "m", numerator, denominator); - addSIname(_s, "s", numerator, denominator); - addSIname(_kg, "kg", numerator, denominator); - addSIname(_K, "K", numerator, denominator); - addSIname(_A, "A", numerator, denominator); - addSIname(_mol, "mol", numerator, denominator); - addSIname(_cd, "cd", numerator, denominator); - addSIname(_rad, "rad", numerator, denominator); - if (denominator.length() > 0) { - if (numerator.length() == 0) { - numerator.append("1"); - } - numerator.append("/"); - numerator.append(denominator.toString()); - } - return numerator.toString(); - } - - private static void addSIname(int si, String name, StringBuilder numerator, - StringBuilder denominator) { - if (si != 0) { - StringBuilder sb = (si > 0) ? numerator : denominator; - if (sb.length() > 0) { - sb.append("*"); - } - sb.append(name); - int power = Math.abs(si); - if (power > 1) { - sb.append("^"); - sb.append(power); - } - } - } - - /** - * Checks whether the unit has a special type, i.e. not a SI unit. - * - * @return true if the type is special, otherwise false. - */ - private boolean isSpecial() { - return (type & x_MASK) != 0; - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/package-info.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/package-info.java deleted file mode 100644 index bac289ab2..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/measurement/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Measurement Package Version 1.0. - * - *

- * Bundles wishing to use this package must list the package in the - * Import-Package header of the bundle's manifest. - * - *

- * Example import for consumers using the API in this package: - *

- * {@code Import-Package: org.osgi.util.measurement; version="[1.0,2.0)"} - * - * @author $Id$ - */ - -@Version("1.0.2") -package org.osgi.util.measurement; - -import org.osgi.annotation.versioning.Version; diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/position/Position.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/position/Position.java deleted file mode 100644 index 0e637b36c..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/position/Position.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2002, 2013). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.position; - -import org.osgi.util.measurement.Measurement; -import org.osgi.util.measurement.Unit; - -/** - * Position represents a geographic location, based on the WGS84 System (World - * Geodetic System 1984). - *

- * The {@code org.osgi.util.measurement.Measurement} class is used to represent - * the values that make up a position. - *

- *

- * A given position object may lack any of it's components, i.e. the altitude - * may not be known. Such missing values will be represented by null. - *

- * Position does not override the implementation of either equals() or - * hashCode() because it is not clear how missing values should be handled. It - * is up to the user of a position to determine how best to compare two position - * objects. A {@code Position} object is immutable. - * - * @Immutable - * @author $Id$ - */ -public class Position { - private final Measurement altitude; - private final Measurement longitude; - private final Measurement latitude; - private final Measurement speed; - private final Measurement track; - - /** - * Constructs a {@code Position} object with the given values. - * - * @param lat a {@code Measurement} object specifying the latitude in - * radians, or null - * @param lon a {@code Measurement} object specifying the longitude in - * radians, or null - * @param alt a {@code Measurement} object specifying the altitude in - * meters, or null - * @param speed a {@code Measurement} object specifying the speed in meters - * per second, or null - * @param track a {@code Measurement} object specifying the track in - * radians, or null - */ - public Position(Measurement lat, Measurement lon, Measurement alt, Measurement speed, Measurement track) { - if (lat != null) { - if (!Unit.rad.equals(lat.getUnit())) { - throw new IllegalArgumentException("Invalid Latitude"); - } - } - if (lon != null) { - if (!Unit.rad.equals(lon.getUnit())) { - throw new IllegalArgumentException("Invalid Longitude"); - } - } - if (alt != null) { - if (!Unit.m.equals(alt.getUnit())) { - throw new IllegalArgumentException("Invalid Altitude"); - } - } - if (speed != null) { - if (!Unit.m_s.equals(speed.getUnit())) { - throw new IllegalArgumentException("Invalid Speed"); - } - } - if (track != null) { - if (!Unit.rad.equals(track.getUnit())) { - throw new IllegalArgumentException("Invalid Track"); - } - } - - /* - * Verify the longitude and latitude parameters so they fit the normal - * coordinate system. A latitude is between -90 (south) and +90 (north). - * A longitude is between -180 (Western hemisphere) and +180 (eastern - * hemisphere). This method first normalizes the latitude and longitude - * between +/- 180. If the |latitude| > 90, then the longitude is added - * 180 and the latitude is normalized to fit +/-90. (Example are with - * degrees though radians are used.) No normalization takes place when - * either lon or lat is null. - */ - normalizeLatLon: { - if (lat == null || lon == null) { - break normalizeLatLon; - } - double dlat = lat.getValue(); - double dlon = lon.getValue(); - if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE && dlat <= LAT_RANGE) { - break normalizeLatLon; - } - dlon = normalize(dlon, LON_RANGE); - dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree - // Check if we have to move to other side of the earth - if (dlat > LAT_RANGE || dlat < -LAT_RANGE) { - dlon = normalize(dlon - LON_RANGE, LON_RANGE); - dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE); - } - lon = new Measurement(dlon, lon.getError(), lon.getUnit(), lon.getTime()); - lat = new Measurement(dlat, lat.getError(), lat.getUnit(), lat.getTime()); - } - - /* - * Normalize track to be a value such that: 0 <= value < +2PI. This - * corresponds to 0 deg to +360 deg. 0 is North, 0.5PI is East, PI is - * South, 1.5PI is West - */ - normalizeTrack: { - if (track == null) { - break normalizeTrack; - } - double dtrack = track.getValue(); - if ((0.0D <= dtrack) && (dtrack < TRACK_RANGE)) { - break normalizeTrack; /* value is already normalized */ - } - dtrack %= TRACK_RANGE; - if (dtrack < 0.0D) { - dtrack += TRACK_RANGE; - } - track = new Measurement(dtrack, track.getError(), track.getUnit(), track.getTime()); - } - - this.latitude = lat; - this.longitude = lon; - this.altitude = alt; - this.speed = speed; - this.track = track; - } - - /** - * Returns the altitude of this position in meters. - * - * @return a {@code Measurement} object in {@code Unit.m} representing the - * altitude in meters above the ellipsoid {@code null} if the - * altitude is not known. - */ - public Measurement getAltitude() { - return altitude; - } - - /** - * Returns the longitude of this position in radians. - * - * @return a {@code Measurement} object in {@code Unit.rad} representing the - * longitude, or {@code null} if the longitude is not known. - */ - public Measurement getLongitude() { - return longitude; - } - - /** - * Returns the latitude of this position in radians. - * - * @return a {@code Measurement} object in {@code Unit.rad} representing the - * latitude, or {@code null} if the latitude is not known.. - */ - public Measurement getLatitude() { - return latitude; - } - - /** - * Returns the ground speed of this position in meters per second. - * - * @return a {@code Measurement} object in {@code Unit.m_s} representing the - * speed, or {@code null} if the speed is not known.. - */ - public Measurement getSpeed() { - return speed; - } - - /** - * Returns the track of this position in radians as a compass heading. The - * track is the extrapolation of previous previously measured positions to a - * future position. - * - * @return a {@code Measurement} object in {@code Unit.rad} representing the - * track, or {@code null} if the track is not known.. - */ - public Measurement getTrack() { - return track; - } - - private static final double LON_RANGE = Math.PI; - private static final double LAT_RANGE = Math.PI / 2.0D; - - /** - * This function normalizes the a value according to a range. This is not - * simple modulo (as I thought when I started), but requires some special - * handling. For positive numbers we subtract 2*range from the number so - * that end up between -/+ range. For negative numbers we add this value. - * For example, if the value is 270 and the range is +/- 180. Then sign=1 so - * the (int) factor becomes 270+180/360 = 1. This means that 270-360=-90 is - * the result. (degrees are only used to make it easier to understand, this - * function is agnostic for radians/degrees). The result will be in - * [range,range> The algorithm is not very fast, but it handling the - * [> ranges made it very messy using integer arithmetic, and this is - * very readable. Note that it is highly unlikely that this method is called - * in normal situations. Normally input values to position are already - * normalized because they come from a GPS. And this is much more readable. - * - * @param value The value that needs adjusting - * @param range -range = < value < range - */ - private static double normalize(double value, double range) { - double twiceRange = 2.0D * range; - while (value >= range) { - value -= twiceRange; - } - while (value < -range) { - value += twiceRange; - } - return value; - } - - private static final double TRACK_RANGE = Math.PI * 2.0D; -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/position/package-info.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/position/package-info.java deleted file mode 100644 index b67b8069b..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/position/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Position Package Version 1.0. - * - *

- * Bundles wishing to use this package must list the package in the - * Import-Package header of the bundle's manifest. - * - *

- * Example import for consumers using the API in this package: - *

- * {@code Import-Package: org.osgi.util.position; version="[1.0,2.0)"} - * - * @author $Id$ - */ - -@Version("1.0.1") -package org.osgi.util.position; - -import org.osgi.annotation.versioning.Version; diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java deleted file mode 100644 index 6ab8f936f..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2017). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static java.util.Objects.requireNonNull; - -import org.osgi.annotation.versioning.ProviderType; - -/** - * A Deferred Promise resolution. - * - *

- * Instances of this class can be used to create a {@link Promise} that can be - * resolved in the future. The {@link #getPromise() associated} Promise can be - * successfully resolved with {@link #resolve(Object)} or resolved with a - * failure with {@link #fail(Throwable)}. It can also be resolved with the - * resolution of another promise using {@link #resolveWith(Promise)}. - * - *

- * The associated Promise can be provided to any one, but the Deferred object - * should be made available only to the party that will responsible for - * resolving the Promise. - * - * @param The value type associated with the created Promise. - * - * @Immutable - * @author $Id$ - */ -@ProviderType -public class Deferred { - /** - * The Promise associated with this Deferred. - */ - private final DeferredPromiseImpl promise; - - /** - * Create a new Deferred. - *

- * The {@link #getPromise() associated promise} will use the default - * callback executor and default scheduled executor. - * - * @see PromiseFactory#deferred() - */ - public Deferred() { - this(PromiseFactory.defaultFactory); - } - - /** - * Create a new Deferred with the specified callback and scheduled - * executors. - * - * @param factory The factory to use for callbacks and scheduled operations. - * @since 1.1 - */ - Deferred(PromiseFactory factory) { - promise = new DeferredPromiseImpl<>(factory); - } - - /** - * Returns the Promise associated with this Deferred. - *

- * All Promise objects created by the associated Promise will use the - * executors of the associated Promise. - * - * @return The Promise associated with this Deferred. - */ - public Promise getPromise() { - return promise; - } - - /** - * Successfully resolve the Promise associated with this Deferred. - * - *

- * After the associated Promise is resolved with the specified value, all - * registered {@link Promise#onResolve(Runnable) callbacks} are called and - * any {@link Promise#then(Success, Failure) chained} Promises are resolved. - * This may occur asynchronously to this method. - *

- * Resolving the associated Promise happens-before any registered - * callback is called. That is, in a registered callback, - * {@link Promise#isDone()} must return {@code true} and - * {@link Promise#getValue()} and {@link Promise#getFailure()} must not - * block. - * - * @param value The value of the resolved Promise. - * @throws IllegalStateException If the associated Promise was already - * resolved. - */ - public void resolve(T value) { - promise.resolve(value, null); - } - - /** - * Fail the Promise associated with this Deferred. - * - *

- * After the associated Promise is resolved with the specified failure, all - * registered {@link Promise#onResolve(Runnable) callbacks} are called and - * any {@link Promise#then(Success, Failure) chained} Promises are resolved. - * This may occur asynchronously to this method. - *

- * Resolving the associated Promise happens-before any registered - * callback is called. That is, in a registered callback, - * {@link Promise#isDone()} must return {@code true} and - * {@link Promise#getValue()} and {@link Promise#getFailure()} must not - * block. - * - * @param failure The failure of the resolved Promise. Must not be - * {@code null}. - * @throws IllegalStateException If the associated Promise was already - * resolved. - */ - public void fail(Throwable failure) { - promise.resolve(null, requireNonNull(failure)); - } - - /** - * Resolve the Promise associated with this Deferred with the specified - * Promise. - * - *

- * If the specified Promise is successfully resolved, the associated Promise - * is resolved with the value of the specified Promise. If the specified - * Promise is resolved with a failure, the associated Promise is resolved - * with the failure of the specified Promise. - * - *

- * After the associated Promise is resolved with the specified Promise, all - * registered {@link Promise#onResolve(Runnable) callbacks} are called and - * any {@link Promise#then(Success, Failure) chained} Promises are resolved. - * This may occur asynchronously to this method. - *

- * Resolving the associated Promise happens-before any registered - * callback is called. That is, in a registered callback, - * {@link Promise#isDone()} must return {@code true} and - * {@link Promise#getValue()} and {@link Promise#getFailure()} must not - * block. - * - * @param with A Promise whose value or failure must be used to resolve the - * associated Promise. Must not be {@code null}. - * @return A Promise that is resolved only when the associated Promise is - * resolved by the specified Promise. The returned Promise must be - * successfully resolved with the value {@code null}, if the - * associated Promise was resolved by the specified Promise. The - * returned Promise must be resolved with a failure of - * {@link IllegalStateException}, if the associated Promise was - * already resolved when the specified Promise was resolved. - */ - public Promise resolveWith(Promise with) { - return promise.resolveWith(with); - } - - /** - * Returns a string representation of the associated Promise. - * - * @return A string representation of the associated Promise. - * @since 1.1 - */ - @Override - public String toString() { - return promise.toString(); - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/DeferredPromiseImpl.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/DeferredPromiseImpl.java deleted file mode 100644 index 3969a37c6..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/DeferredPromiseImpl.java +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2021). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static java.util.Objects.requireNonNull; - -import java.lang.reflect.InvocationTargetException; -import java.util.NoSuchElementException; -import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.osgi.util.function.Consumer; -import org.osgi.util.function.Function; -import org.osgi.util.function.Predicate; - -/** - * Deferred Promise implementation. - *

- * This class is not used directly by clients. Clients should use - * {@link PromiseFactory#deferred()} to create a {@link Deferred} which can be - * used to obtain a Promise whose resolution can be deferred. - * - * @param The result type associated with the Promise. - * @since 1.1 - * @ThreadSafe - * @author $Id$ - */ -final class DeferredPromiseImpl extends PromiseImpl { - /** - * A CountDownLatch to manage the resolved state of this Promise. - *

- * This object is used as the synchronizing object to provide a critical - * section in {@link #tryResolve(Object, Throwable)} so that only a single - * thread can write the resolved state variables and open the latch. - *

- * The resolved state variables, {@link #value} and {@link #fail}, must only - * be written when the latch is closed (getCount() != 0) and must only be - * read when the latch is open (getCount() == 0). The latch state must - * always be checked before writing or reading since the resolved state - * variables' memory consistency is guarded by the latch. - */ - private final CountDownLatch resolved; - - /** - * The value of this Promise if successfully resolved. - * - * @see resolved - */ - // @GuardedBy("resolved") - private T value; - - /** - * The failure of this Promise if resolved with a failure or {@code null} if - * successfully resolved. - * - * @see resolved - */ - // @GuardedBy("resolved") - private Throwable fail; - - /** - * Initialize this Promise. - * - * @param factory The factory to use for callbacks and scheduled operations. - */ - DeferredPromiseImpl(PromiseFactory factory) { - super(factory); - resolved = new CountDownLatch(1); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isDone() { - return resolved.getCount() == 0; - } - - /** - * Return a resolved PromiseImpl if this DeferredPromiseImpl is resolved. - * - * @return A ResolvedPromiseImpl holding the value of this - * DeferredPromiseImpl or a FailedPromiseImpl holding the failure of - * this DeferredPromiseImpl or this DeferredPromiseImpl if this - * DeferredPromiseImpl is not resolved. - */ - PromiseImpl orDone() { - // ensure latch open before reading state - if (!isDone()) { - return this; - } - if (fail == null) { - return resolved(value); - } - return failed(fail); - } - - /** - * {@inheritDoc} - */ - @Override - public T getValue() throws InvocationTargetException, InterruptedException { - // ensure latch open before reading state - resolved.await(); - if (fail == null) { - return value; - } - throw new InvocationTargetException(fail); - } - - /** - * {@inheritDoc} - */ - @Override - public Throwable getFailure() throws InterruptedException { - // ensure latch open before reading state - resolved.await(); - return fail; - } - - /** - * {@inheritDoc} - */ - @Override - Result collect() { - // ensure latch open before reading state - if (!isDone()) { - return new Result<>(new AssertionError("promise not resolved")); - } - if (fail == null) { - return new Result<>(value); - } - return new Result<>(fail); - } - - @Override - public String toString() { - // ensure latch open before reading state - if (!isDone()) { - return super.toString() + "[unresolved]"; - } - if (fail == null) { - return super.toString() + "[resolved: " + value + "]"; - } - return super.toString() + "[failed: " + fail + "]"; - } - - /** - * Try to resolve this Promise. - *

- * If this Promise was already resolved, return false. Otherwise, resolve - * this Promise and return true. - * - * @param v The value of this Promise. - * @param f The failure of this Promise. - * @return false if this Promise was already resolved; true if this method - * resolved this Promise. - */ - boolean tryResolve(T v, Throwable f) { - // critical section: only one resolver at a time - synchronized (resolved) { - if (isDone()) { - return false; - } - /* - * The resolved state variables must be set before opening the - * latch. This safely publishes them to be read by other threads - * that must verify the latch is open before reading. - */ - if (f == null) { - value = v; - } else { - fail = f; - } - resolved.countDown(); - } - notifyCallbacks(); // call any registered callbacks - return true; - } - - /** - * Resolve this Promise. - *

- * If this Promise was already resolved, throw IllegalStateException. - * Otherwise, resolve this Promise. - * - * @param v The value of this Promise. - * @param f The failure of this Promise. - * @throws IllegalStateException If this Promise was already resolved. - */ - void resolve(T v, Throwable f) { - if (!tryResolve(v, f)) { - throw new IllegalStateException("Already resolved"); - } - } - - /** - * Resolve this Promise with the specified Promise. - *

- * If the specified Promise is successfully resolved, this Promise is - * resolved with the value of the specified Promise. If the specified - * Promise is resolved with a failure, this Promise is resolved with the - * failure of the specified Promise. - * - * @param with A Promise whose value or failure must be used to resolve this - * Promise. Must not be {@code null}. - * @return A Promise that is resolved only when this Promise is resolved by - * the specified Promise. The returned Promise must be successfully - * resolved with the value {@code null}, if this Promise was - * resolved by the specified Promise. The returned Promise must be - * resolved with a failure of {@link IllegalStateException}, if this - * Promise was already resolved when the specified Promise was - * resolved. - */ - Promise resolveWith(Promise< ? extends T> with) { - DeferredPromiseImpl chained = deferred(); - with.onResolve(chained.new ResolveWith<>(with, this)); - return chained.orDone(); - } - - /** - * A callback used to resolve a Promise with another Promise for the - * {@link #resolveWith(Promise)} method. - * - * @Immutable - */ - private final class ResolveWith

implements Runnable { - private final Promise< ? extends P> promise; - private final DeferredPromiseImpl

target; - - ResolveWith(Promise< ? extends P> promise, - DeferredPromiseImpl

target) { - this.promise = requireNonNull(promise); - this.target = requireNonNull(target); - } - - @Override - public void run() { - Throwable f = null; - Result

result = collect(promise); - try { - target.resolve(result.value, result.fail); - } catch (Throwable e) { - f = e; // propagate new exception - } - tryResolve(null, f); - } - } - - /** - * A callback used to chain promises for the - * {@link PromiseImpl#then(Success, Failure)} method. - * - * @Immutable - */ - final class Then

implements Runnable { - private final PromiseImpl

promise; - private final Success success; - private final Failure failure; - - @SuppressWarnings("unchecked") - Then(PromiseImpl

promise, Success< ? super P, ? extends T> success, - Failure failure) { - this.promise = requireNonNull(promise); - this.success = (Success) success; - this.failure = failure; - } - - @Override - public void run() { - Result

result = promise.collect(); - if (result.fail != null) { - if (failure != null) { - try { - failure.fail(promise); - } catch (Throwable e) { - result.fail = e; // propagate new exception - } - } - } else if (success != null) { - Promise< ? extends T> returned = null; - try { - returned = success.call(promise); - } catch (Throwable e) { - result.fail = e; // propagate new exception - } - if (returned != null) { - returned.onResolve(new Chain(returned)); - return; - } - } - tryResolve(null, result.fail); - } - } - - /** - * A callback used to resolve the chained Promise when the Promise is - * resolved. - * - * @Immutable - */ - private final class Chain implements Runnable { - private final Promise< ? extends T> promise; - - Chain(Promise< ? extends T> promise) { - this.promise = requireNonNull(promise); - } - - @Override - public void run() { - Result result = collect(promise); - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used to resolve the chained Promise when the PromiseImpl is - * resolved. - * - * @Immutable - */ - private final class ChainImpl implements Runnable { - private final PromiseImpl promise; - - ChainImpl(PromiseImpl promise) { - this.promise = requireNonNull(promise); - } - - @Override - public void run() { - Result result = promise.collect(); - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#thenAccept(Consumer)} method. - * - * @Immutable - */ - final class ThenAccept implements Runnable { - private final PromiseImpl promise; - private final Consumer< ? super T> consumer; - - ThenAccept(PromiseImpl promise, Consumer< ? super T> consumer) { - this.promise = requireNonNull(promise); - this.consumer = requireNonNull(consumer); - } - - @Override - public void run() { - Result result = promise.collect(); - if (result.fail == null) { - try { - consumer.accept(result.value); - } catch (Throwable e) { - result.fail = e; - } - } - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#filter(Predicate)} method. - * - * @Immutable - */ - final class Filter implements Runnable { - private final PromiseImpl promise; - private final Predicate< ? super T> predicate; - - Filter(PromiseImpl promise, Predicate< ? super T> predicate) { - this.promise = requireNonNull(promise); - this.predicate = requireNonNull(predicate); - } - - @Override - public void run() { - Result result = promise.collect(); - if (result.fail == null) { - try { - if (!predicate.test(result.value)) { - result.fail = new NoSuchElementException(); - } - } catch (Throwable e) { // propagate new exception - result.fail = e; - } - } - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#map(Function)} method. - * - * @Immutable - */ - final class Map

implements Runnable { - private final PromiseImpl

promise; - private final Function< ? super P, ? extends T> mapper; - - Map(PromiseImpl

promise, Function< ? super P, ? extends T> mapper) { - this.promise = requireNonNull(promise); - this.mapper = requireNonNull(mapper); - } - - @Override - public void run() { - Result

result = promise.collect(); - T v = null; - if (result.fail == null) { - try { - v = mapper.apply(result.value); - } catch (Throwable e) { // propagate new exception - result.fail = e; - } - } - tryResolve(v, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#flatMap(Function)} method. - * - * @Immutable - */ - final class FlatMap

implements Runnable { - private final PromiseImpl

promise; - private final Function< ? super P,Promise< ? extends T>> mapper; - - FlatMap(PromiseImpl

promise, - Function< ? super P,Promise< ? extends T>> mapper) { - this.promise = requireNonNull(promise); - this.mapper = requireNonNull(mapper); - } - - @Override - public void run() { - Result

result = promise.collect(); - if (result.fail == null) { - Promise< ? extends T> flatmap = null; - try { - flatmap = mapper.apply(result.value); - } catch (Throwable e) { // propagate new exception - result.fail = e; - } - if (flatmap != null) { - flatmap.onResolve(new Chain(flatmap)); - return; - } - } - tryResolve(null, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#recover(Function)} method. - * - * @Immutable - */ - final class Recover implements Runnable { - private final PromiseImpl promise; - private final Function, ? extends T> recovery; - - Recover(PromiseImpl promise, - Function, ? extends T> recovery) { - this.promise = requireNonNull(promise); - this.recovery = requireNonNull(recovery); - } - - @Override - public void run() { - Result result = promise.collect(); - if (result.fail != null) { - try { - T v = recovery.apply(promise); - if (v != null) { - result.value = v; - result.fail = null; - } - } catch (Throwable e) { // propagate new exception - result.fail = e; - } - } - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#recoverWith(Function)} method. - * - * @Immutable - */ - final class RecoverWith implements Runnable { - private final PromiseImpl promise; - private final Function,Promise< ? extends T>> recovery; - - RecoverWith(PromiseImpl promise, - Function,Promise< ? extends T>> recovery) { - this.promise = requireNonNull(promise); - this.recovery = requireNonNull(recovery); - } - - @Override - public void run() { - Result result = promise.collect(); - if (result.fail != null) { - Promise< ? extends T> recovered = null; - try { - recovered = recovery.apply(promise); - } catch (Throwable e) { // propagate new exception - result.fail = e; - } - if (recovered != null) { - recovered.onResolve(new Chain(recovered)); - return; - } - } - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#fallbackTo(Promise)} method. - * - * @Immutable - */ - final class FallbackTo implements Runnable { - private final PromiseImpl promise; - private final Promise< ? extends T> fallback; - - FallbackTo(PromiseImpl promise, Promise< ? extends T> fallback) { - this.promise = requireNonNull(promise); - this.fallback = requireNonNull(fallback); - } - - @Override - public void run() { - Result result = promise.collect(); - if (result.fail != null) { - fallback.onResolve(new FallbackChain(fallback, result.fail)); - return; - } - tryResolve(result.value, null); - } - } - - /** - * A callback used to resolve the chained Promise when the fallback Promise - * is resolved. - * - * @Immutable - */ - private final class FallbackChain implements Runnable { - private final Promise< ? extends T> fallback; - private final Throwable failure; - - FallbackChain(Promise< ? extends T> fallback, Throwable failure) { - this.fallback = requireNonNull(fallback); - this.failure = requireNonNull(failure); - } - - @Override - public void run() { - Result result = collect(fallback); - if (result.fail != null) { - result.fail = failure; - } - tryResolve(result.value, result.fail); - } - } - - /** - * A callback used by the {@link PromiseImpl#timeout(long)} method to - * schedule the timeout and to resolve the chained Promise and cancel the - * timeout. - * - * @Immutable - */ - final class Timeout implements Runnable { - private final PromiseImpl promise; - private final ScheduledFuture< ? > future; - - Timeout(PromiseImpl promise, long millis) { - this.promise = requireNonNull(promise); - if (promise.isDone()) { - this.future = null; - } else { - FailedPromiseImpl timedout = failed(new TimeoutException()); - Runnable operation = new ChainImpl(timedout); - this.future = schedule(operation, millis, TimeUnit.MILLISECONDS); - } - } - - @Override - public void run() { - Result result = promise.collect(); - tryResolve(result.value, result.fail); - if (future != null) { - future.cancel(false); - } - } - } - - /** - * A callback used by the {@link PromiseImpl#delay(long)} method to delay - * chaining a promise. - * - * @Immutable - */ - final class Delay implements Runnable { - private final Runnable operation; - private final long millis; - - Delay(PromiseImpl promise, long millis) { - this.operation = new ChainImpl(promise); - this.millis = millis; - } - - @Override - public void run() { - schedule(operation, millis, TimeUnit.MILLISECONDS); - } - } - - /** - * A callback used by the {@link PromiseFactory#submit(Callable)} method. - * - * @Immutable - */ - final class Submit implements Runnable { - private final Callable< ? extends T> task; - - Submit(Callable< ? extends T> task) { - this.task = requireNonNull(task); - } - - @Override - public void run() { - try { - tryResolve(task.call(), null); - } catch (Throwable t) { - tryResolve(null, t); - } - } - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/FailedPromiseImpl.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/FailedPromiseImpl.java deleted file mode 100644 index 9bec4b56c..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/FailedPromiseImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2017, 2021). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static java.util.Objects.requireNonNull; - -import java.lang.reflect.InvocationTargetException; - -import org.osgi.util.function.Consumer; -import org.osgi.util.function.Function; -import org.osgi.util.function.Predicate; - -/** - * Failed Promise implementation. - *

- * This class is not used directly by clients. Clients should use - * {@link PromiseFactory#failed(Throwable)} to create a failed {@link Promise}. - * - * @param The result type associated with the Promise. - * @since 1.1 - * @ThreadSafe - * @author $Id$ - */ -final class FailedPromiseImpl extends PromiseImpl { - /** - * The failure of this failed Promise. - */ - private final Throwable fail; - - /** - * Initialize this failed Promise. - * - * @param fail The failure of this failed Promise. Must not be {@code null}. - * @param factory The factory to use for callbacks and scheduled operations. - */ - FailedPromiseImpl(Throwable fail, PromiseFactory factory) { - super(factory); - this.fail = requireNonNull(fail); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isDone() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public T getValue() throws InvocationTargetException { - throw new InvocationTargetException(fail); - } - - /** - * {@inheritDoc} - */ - @Override - public Throwable getFailure() { - return fail; - } - - /** - * {@inheritDoc} - */ - @Override - Result collect() { - return new Result<>(fail); - } - - @Override - public String toString() { - return super.toString() + "[failed: " + fail + "]"; - } - - /** - * Coerce the value type of this FailedPromiseImpl. - * - * @return This FailedPromiseImpl. - */ - @SuppressWarnings("unchecked") - private FailedPromiseImpl coerce() { - return (FailedPromiseImpl) this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise onSuccess(Consumer< ? super T> success) { - requireNonNull(success); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise then(Success< ? super T, ? extends R> success, - Failure failure) { - if (failure == null) { - return coerce(); - } - return super.then(success, failure); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise thenAccept(Consumer< ? super T> consumer) { - requireNonNull(consumer); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise filter(Predicate< ? super T> predicate) { - requireNonNull(predicate); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise map(Function< ? super T, ? extends R> mapper) { - requireNonNull(mapper); - return coerce(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise flatMap( - Function< ? super T,Promise< ? extends R>> mapper) { - requireNonNull(mapper); - return coerce(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise timeout(long millis) { - return this; - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/FailedPromisesException.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/FailedPromisesException.java deleted file mode 100644 index 95546abe5..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/FailedPromisesException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import java.util.Collection; -import java.util.Collections; - -/** - * Promise failure exception for a collection of failed Promises. - * - * @author $Id$ - */ -public class FailedPromisesException extends RuntimeException { - private static final long serialVersionUID = 1L; - private final Collection> failed; - - /** - * Create a new FailedPromisesException with the specified Promises. - * - * @param failed A collection of Promises that have been resolved with a - * failure. Must not be {@code null}, must not be empty and all of - * the elements in the collection must not be {@code null}. - * @param cause The cause of this exception. This is typically the failure - * of the first Promise in the specified collection. - */ - public FailedPromisesException(Collection> failed, Throwable cause) { - super(cause); - this.failed = Collections.unmodifiableCollection(failed); - } - - /** - * Returns the collection of Promises that have been resolved with a - * failure. - * - * @return The collection of Promises that have been resolved with a - * failure. The returned collection is unmodifiable. - */ - public Collection> getFailedPromises() { - return failed; - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Failure.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Failure.java deleted file mode 100644 index 9d491b595..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Failure.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2015). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import org.osgi.annotation.versioning.ConsumerType; - -/** - * Failure callback for a Promise. - * - *

- * A Failure callback is registered with a {@link Promise} using the - * {@link Promise#then(Success, Failure)} method and is called if the Promise is - * resolved with a failure. - * - *

- * This is a functional interface and can be used as the assignment target for a - * lambda expression or method reference. - * - * @ThreadSafe - * @author $Id$ - */ -@ConsumerType -@FunctionalInterface -public interface Failure { - /** - * Failure callback for a Promise. - * - *

- * This method is called if the Promise with which it is registered resolves - * with a failure. - * - *

- * In the remainder of this description we will refer to the Promise - * returned by {@link Promise#then(Success, Failure)} when this Failure - * callback was registered as the chained Promise. - * - *

- * If this methods completes normally, the chained Promise must be failed - * with the same exception which failed the resolved Promise. If this method - * throws an exception, the chained Promise must be failed with the thrown - * exception. - * - * @param resolved The failed resolved {@link Promise}. - * @throws Exception The chained Promise must be failed with the thrown - * exception. - */ - void fail(Promise resolved) throws Exception; -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promise.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promise.java deleted file mode 100644 index 340a61ee6..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promise.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2018). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import java.lang.reflect.InvocationTargetException; - -import org.osgi.annotation.versioning.ProviderType; -import org.osgi.util.function.Consumer; -import org.osgi.util.function.Function; -import org.osgi.util.function.Predicate; - -/** - * A Promise of a value. - *

- * A Promise represents a future value. It handles the interactions for - * asynchronous processing. A {@link Deferred} object can be used to create a - * Promise and later resolve the Promise. A Promise is used by the caller of an - * asynchronous function to get the result or handle the error. The caller can - * either get a callback when the Promise is resolved with a value or an error, - * or the Promise can be used in chaining. In chaining, callbacks are provided - * that receive the resolved Promise, and a new Promise is generated that - * resolves based upon the result of a callback. - *

- * Both {@link #onResolve(Runnable) callbacks} and - * {@link #then(Success, Failure) chaining} can be repeated any number of times, - * even after the Promise has been resolved. - *

- * Example callback usage: - * - *

- * Promise<String> foo = foo();
- * foo.onResolve(() -> System.out.println("resolved"));
- * 
- * - * Example chaining usage; - * - *
- * Success<String,String> doubler = p -> Promises
- * 		.resolved(p.getValue() + p.getValue());
- * Promise<String> foo = foo().then(doubler).then(doubler);
- * 
- * - * @param The value type associated with this Promise. - * @ThreadSafe - * @author $Id$ - */ -@ProviderType -public interface Promise { - - /** - * Returns whether this Promise has been resolved. - * - *

- * This Promise may be successfully resolved or resolved with a failure. - * - * @return {@code true} if this Promise was resolved either successfully or - * with a failure; {@code false} if this Promise is unresolved. - */ - boolean isDone(); - - /** - * Returns the value of this Promise. - * - *

- * If this Promise is not {@link #isDone() resolved}, this method must block - * and wait for this Promise to be resolved before completing. - * - *

- * If this Promise was successfully resolved, this method returns with the - * value of this Promise. If this Promise was resolved with a failure, this - * method must throw an {@code InvocationTargetException} with the - * {@link #getFailure() failure exception} as the cause. - * - * @return The value of this resolved Promise. - * @throws InvocationTargetException If this Promise was resolved with a - * failure. The cause of the {@code InvocationTargetException} is - * the failure exception. - * @throws InterruptedException If the current thread was interrupted while - * waiting. - */ - T getValue() throws InvocationTargetException, InterruptedException; - - /** - * Returns the failure of this Promise. - * - *

- * If this Promise is not {@link #isDone() resolved}, this method must block - * and wait for this Promise to be resolved before completing. - * - *

- * If this Promise was resolved with a failure, this method returns with the - * failure of this Promise. If this Promise was successfully resolved, this - * method must return {@code null}. - * - * @return The failure of this resolved Promise or {@code null} if this - * Promise was successfully resolved. - * @throws InterruptedException If the current thread was interrupted while - * waiting. - */ - Throwable getFailure() throws InterruptedException; - - /** - * Register a callback to be called when this Promise is resolved. - *

- * The specified callback is called when this Promise is resolved either - * successfully or with a failure. - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - *

- * Resolving this Promise happens-before any registered callback is - * called. That is, in a registered callback, {@link #isDone()} must return - * {@code true} and {@link #getValue()} and {@link #getFailure()} must not - * block. - *

- * A callback may be called on a different thread than the thread which - * registered the callback. So the callback must be thread safe but can rely - * upon that the registration of the callback happens-before the - * registered callback is called. - * - * @param callback The callback to be called when this Promise is resolved. - * Must not be {@code null}. - * @return This Promise. - */ - Promise onResolve(Runnable callback); - - /** - * Register a callback to be called with the result of this Promise when - * this Promise is resolved successfully. The callback will not be called if - * this Promise is resolved with a failure. - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - *

- * Resolving this Promise happens-before any registered callback is - * called. That is, in a registered callback, {@link #isDone()} must return - * {@code true} and {@link #getValue()} and {@link #getFailure()} must not - * block. - *

- * A callback may be called on a different thread than the thread which - * registered the callback. So the callback must be thread safe but can rely - * upon that the registration of the callback happens-before the - * registered callback is called. - * - * @param success The Consumer callback that receives the value of this - * Promise. Must not be {@code null}. - * @return This Promise. - * @since 1.1 - */ - Promise onSuccess(Consumer< ? super T> success); - - /** - * Register a callback to be called with the failure for this Promise when - * this Promise is resolved with a failure. The callback will not be called - * if this Promise is resolved successfully. - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - *

- * Resolving this Promise happens-before any registered callback is - * called. That is, in a registered callback, {@link #isDone()} must return - * {@code true} and {@link #getValue()} and {@link #getFailure()} must not - * block. - *

- * A callback may be called on a different thread than the thread which - * registered the callback. So the callback must be thread safe but can rely - * upon that the registration of the callback happens-before the - * registered callback is called. - * - * @param failure The Consumer callback that receives the failure of this - * Promise. Must not be {@code null}. - * @return This Promise. - * @since 1.1 - */ - Promise onFailure(Consumer< ? super Throwable> failure); - - /** - * Chain a new Promise to this Promise with Success and Failure callbacks. - *

- * The specified {@link Success} callback is called when this Promise is - * successfully resolved and the specified {@link Failure} callback is - * called when this Promise is resolved with a failure. - *

- * This method returns a new Promise which is chained to this Promise. The - * returned Promise must be resolved when this Promise is resolved after the - * specified Success or Failure callback is executed. The result of the - * executed callback must be used to resolve the returned Promise. Multiple - * calls to this method can be used to create a chain of promises which are - * resolved in sequence. - *

- * If this Promise is successfully resolved, the Success callback is - * executed and the result Promise, if any, or thrown exception is used to - * resolve the returned Promise from this method. If this Promise is - * resolved with a failure, the Failure callback is executed and the - * returned Promise from this method is failed. - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - *

- * Resolving this Promise happens-before any registered callback is - * called. That is, in a registered callback, {@link #isDone()} must return - * {@code true} and {@link #getValue()} and {@link #getFailure()} must not - * block. - *

- * A callback may be called on a different thread than the thread which - * registered the callback. So the callback must be thread safe but can rely - * upon that the registration of the callback happens-before the - * registered callback is called. - * - * @param The value type associated with the returned Promise. - * @param success The Success callback to be called when this Promise is - * successfully resolved. May be {@code null} if no Success - * callback is required. In this case, the returned Promise must - * be resolved with the value {@code null} when this Promise is - * successfully resolved. - * @param failure The Failure callback to be called when this Promise is - * resolved with a failure. May be {@code null} if no Failure - * callback is required. - * @return A new Promise which is chained to this Promise. The returned - * Promise must be resolved when this Promise is resolved after the - * specified Success or Failure callback, if any, is executed. - */ - Promise then(Success success, Failure failure); - - /** - * Chain a new Promise to this Promise with a Success callback. - *

- * This method performs the same function as calling - * {@link #then(Success, Failure)} with the specified Success callback and - * {@code null} for the Failure callback. - * - * @param The value type associated with the returned Promise. - * @param success The Success callback to be called when this Promise is - * successfully resolved. May be {@code null} if no Success - * callback is required. In this case, the returned Promise must - * be resolved with the value {@code null} when this Promise is - * successfully resolved. - * @return A new Promise which is chained to this Promise. The returned - * Promise must be resolved when this Promise is resolved after the - * specified Success, if any, is executed. - * @see #then(Success, Failure) - */ - Promise then(Success success); - - /** - * Chain a new Promise to this Promise with a Consumer callback that - * receives the value of this Promise when it is successfully resolved. - *

- * The specified {@link Consumer} is called when this Promise is resolved - * successfully. - *

- * This method returns a new Promise which is chained to this Promise. The - * returned Promise must be resolved when this Promise is resolved after the - * specified callback is executed. If the callback throws an exception, the - * returned Promise is failed with that exception. Otherwise the returned - * Promise is resolved with the success value from this Promise. - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - *

- * Resolving this Promise happens-before any registered callback is - * called. That is, in a registered callback, {@link #isDone()} must return - * {@code true} and {@link #getValue()} and {@link #getFailure()} must not - * block. - *

- * A callback may be called on a different thread than the thread which - * registered the callback. So the callback must be thread safe but can rely - * upon that the registration of the callback happens-before the - * registered callback is called. - * - * @param consumer The Consumer callback that receives the value of this - * Promise. Must not be {@code null}. - * @return A new Promise which is chained to this Promise. The returned - * Promise must be resolved when this Promise is resolved after the - * specified Consumer is executed. - * @since 1.1 - */ - Promise thenAccept(Consumer< ? super T> consumer); - - /** - * Filter the value of this Promise. - *

- * If this Promise is successfully resolved, the returned Promise must - * either be resolved with the value of this Promise, if the specified - * Predicate accepts that value, or failed with a - * {@code NoSuchElementException}, if the specified Predicate does not - * accept that value. If the specified Predicate throws an exception, the - * returned Promise must be failed with the exception. - *

- * If this Promise is resolved with a failure, the returned Promise must be - * failed with that failure. - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - * - * @param predicate The Predicate to evaluate the value of this Promise. - * Must not be {@code null}. - * @return A Promise that filters the value of this Promise. - */ - Promise filter(Predicate predicate); - - /** - * Map the value of this Promise. - * - *

- * If this Promise is successfully resolved, the returned Promise must be - * resolved with the value of specified Function as applied to the value of - * this Promise. If the specified Function throws an exception, the returned - * Promise must be failed with the exception. - * - *

- * If this Promise is resolved with a failure, the returned Promise must be - * failed with that failure. - * - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - * - * @param The value type associated with the returned Promise. - * @param mapper The Function that must map the value of this Promise to the - * value that must be used to resolve the returned Promise. Must not - * be {@code null}. - * @return A Promise that returns the value of this Promise as mapped by the - * specified Function. - */ - Promise map(Function mapper); - - /** - * FlatMap the value of this Promise. - * - *

- * If this Promise is successfully resolved, the returned Promise must be - * resolved with the Promise from the specified Function as applied to the - * value of this Promise. If the specified Function throws an exception, the - * returned Promise must be failed with the exception. - * - *

- * If this Promise is resolved with a failure, the returned Promise must be - * failed with that failure. - * - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - * - * @param The value type associated with the returned Promise. - * @param mapper The Function that must flatMap the value of this Promise to - * a Promise that must be used to resolve the returned Promise. Must - * not be {@code null}. - * @return A Promise that returns the value of this Promise as mapped by the - * specified Function. - */ - Promise flatMap(Function> mapper); - - /** - * Recover from a failure of this Promise with a recovery value. - * - *

- * If this Promise is successfully resolved, the returned Promise must be - * resolved with the value of this Promise. - * - *

- * If this Promise is resolved with a failure, the specified Function is - * applied to this Promise to produce a recovery value. - *

    - *
  • If the recovery value is not {@code null}, the returned Promise must - * be resolved with the recovery value.
  • - *
  • If the recovery value is {@code null}, the returned Promise must be - * failed with the failure of this Promise.
  • - *
  • If the specified Function throws an exception, the returned Promise - * must be failed with that exception.
  • - *
- * - *

- * To recover from a failure of this Promise with a recovery value of - * {@code null}, the {@link #recoverWith(Function)} method must be used. The - * specified Function for {@link #recoverWith(Function)} can return - * {@code Promises.resolved(null)} to supply the desired {@code null} value. - * - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - * - * @param recovery If this Promise resolves with a failure, the specified - * Function is called to produce a recovery value to be used to - * resolve the returned Promise. Must not be {@code null}. - * @return A Promise that resolves with the value of this Promise or - * recovers from the failure of this Promise. - */ - Promise recover(Function, ? extends T> recovery); - - /** - * Recover from a failure of this Promise with a recovery Promise. - * - *

- * If this Promise is successfully resolved, the returned Promise must be - * resolved with the value of this Promise. - * - *

- * If this Promise is resolved with a failure, the specified Function is - * applied to this Promise to produce a recovery Promise. - *

    - *
  • If the recovery Promise is not {@code null}, the returned Promise - * must be resolved with the recovery Promise.
  • - *
  • If the recovery Promise is {@code null}, the returned Promise must be - * failed with the failure of this Promise.
  • - *
  • If the specified Function throws an exception, the returned Promise - * must be failed with that exception.
  • - *
- * - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - * - * @param recovery If this Promise resolves with a failure, the specified - * Function is called to produce a recovery Promise to be used to - * resolve the returned Promise. Must not be {@code null}. - * @return A Promise that resolves with the value of this Promise or - * recovers from the failure of this Promise. - */ - Promise recoverWith(Function, Promise> recovery); - - /** - * Fall back to the value of the specified Promise if this Promise fails. - * - *

- * If this Promise is successfully resolved, the returned Promise must be - * resolved with the value of this Promise. - * - *

- * If this Promise is resolved with a failure, the successful result of the - * specified Promise is used to resolve the returned Promise. If the - * specified Promise is resolved with a failure, the returned Promise must - * be failed with the failure of this Promise rather than the failure of the - * specified Promise. - * - *

- * This method may be called at any time including before and after this - * Promise has been resolved. - * - * @param fallback The Promise whose value must be used to resolve the - * returned Promise if this Promise resolves with a failure. Must not - * be {@code null}. - * @return A Promise that returns the value of this Promise or falls back to - * the value of the specified Promise. - */ - Promise fallbackTo(Promise fallback); - - /** - * Time out the resolution of this Promise. - *

- * If this Promise is successfully resolved before the timeout, the returned - * Promise is resolved with the value of this Promise. If this Promise is - * resolved with a failure before the timeout, the returned Promise is - * resolved with the failure of this Promise. If the timeout is reached - * before this Promise is resolved, the returned Promise is failed with a - * {@link TimeoutException}. - * - * @param milliseconds The time to wait in milliseconds. Zero and negative - * time is treated as an immediate timeout. - * @return A Promise that is resolved when either this Promise is resolved - * or the specified timeout is reached. - * @since 1.1 - */ - Promise timeout(long milliseconds); - - /** - * Delay after the resolution of this Promise. - *

- * Once this Promise is resolved, resolve the returned Promise with this - * Promise after the specified delay. - * - * @param milliseconds The time to delay in milliseconds. Zero and negative - * time is treated as no delay. - * @return A Promise that is resolved with this Promise after this Promise - * is resolved and the specified delay has elapsed. - * @since 1.1 - */ - Promise delay(long milliseconds); -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/PromiseFactory.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/PromiseFactory.java deleted file mode 100644 index 8c4cd82d1..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/PromiseFactory.java +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2017, 2021). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static java.util.Objects.requireNonNull; -import static org.osgi.util.promise.PromiseImpl.uncaughtException; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.RunnableScheduledFuture; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import org.osgi.annotation.versioning.ConsumerType; -import org.osgi.util.promise.PromiseImpl.Result; - -/** - * Promise factory to create Deferred and Promise objects. - *

- * Instances of this class can be used to create Deferred and Promise objects - * which use the executors used to construct this object for any callback or - * scheduled operation execution. - * - * @Immutable - * @author $Id$ - * @since 1.1 - */ -@ConsumerType -public class PromiseFactory { - /** - * The default factory which uses the default callback executor and default - * scheduled executor. - */ - final static PromiseFactory defaultFactory = new PromiseFactory( - null, null); - - /** - * The executor to use for callbacks. If {@code null}, the default callback - * executor is used. - */ - private final Executor callbackExecutor; - /** - * The executor to use for scheduled operations. If {@code null}, the - * default scheduled executor is used. - */ - private final ScheduledExecutorService scheduledExecutor; - - private final boolean allowCurrentThread; - - /** - * Create a new PromiseFactory with the specified callback executor. - *

- * The default scheduled executor will be used. - * - * @param callbackExecutor The executor to use for callbacks. {@code null} - * can be specified for the default callback executor. - */ - public PromiseFactory(Executor callbackExecutor) { - this(callbackExecutor, null); - } - - /** - * Create a new PromiseFactory with the specified callback executor and - * specified scheduled executor. - * - * @param callbackExecutor The executor to use for callbacks. {@code null} - * can be specified for the default callback executor. - * @param scheduledExecutor The scheduled executor for use for scheduled - * operations. {@code null} can be specified for the default - * scheduled executor. - */ - public PromiseFactory(Executor callbackExecutor, - ScheduledExecutorService scheduledExecutor) { - this.callbackExecutor = callbackExecutor; - this.scheduledExecutor = scheduledExecutor; - allowCurrentThread = Boolean.parseBoolean(System.getProperty( - "org.osgi.util.promise.allowCurrentThread", - Boolean.TRUE.toString())); - - } - - /** - * Returns the executor to use for callbacks. - * - * @return The executor to use for callbacks. This will be the default - * callback executor if {@code null} was specified for the callback - * executor when this PromiseFactory was created. - */ - public Executor executor() { - if (callbackExecutor == null) { - return DefaultExecutors.callbackExecutor(); - } - return callbackExecutor; - } - - /** - * Returns the scheduled executor to use for scheduled operations. - * - * @return The scheduled executor to use for scheduled operations. This will - * be the default scheduled executor if {@code null} was specified - * for the scheduled executor when this PromiseFactory was created. - */ - public ScheduledExecutorService scheduledExecutor() { - if (scheduledExecutor == null) { - return DefaultExecutors.scheduledExecutor(); - } - return scheduledExecutor; - } - - /** - * Create a new Deferred with the callback executor and scheduled executor - * of this PromiseFactory object. - *

- * Use this method instead of {@link Deferred#Deferred()} to create a new - * {@link Deferred} whose associated Promise uses executors other than the - * default executors. - * - * @param The value type associated with the returned Deferred. - * @return A new {@link Deferred} with the callback and scheduled executors - * of this PromiseFactory object - */ - public Deferred deferred() { - return new Deferred<>(this); - } - - /** - * Returns a new Promise that has been resolved with the specified value. - *

- * The returned Promise uses the callback executor and scheduled executor of - * this PromiseFactory object. - *

- * Use this method instead of {@link Promises#resolved(Object)} to create a - * Promise which uses executors other than the default executors. - * - * @param The value type associated with the returned Promise. - * @param value The value of the resolved Promise. - * @return A new Promise that has been resolved with the specified value. - */ - public Promise resolved(T value) { - return new ResolvedPromiseImpl<>(value, this); - } - - /** - * Returns a new Promise that has been resolved with the specified failure. - *

- * The returned Promise uses the callback executor and scheduled executor of - * this PromiseFactory object. - *

- * Use this method instead of {@link Promises#failed(Throwable)} to create a - * Promise which uses executors other than the default executors. - * - * @param The value type associated with the returned Promise. - * @param failure The failure of the resolved Promise. Must not be - * {@code null}. - * @return A new Promise that has been resolved with the specified failure. - */ - public Promise failed(Throwable failure) { - return new FailedPromiseImpl<>(failure, this); - } - - /** - * Returns a new Promise that will hold the result of the specified task. - *

- * The returned Promise uses the callback executor and scheduled executor of - * this PromiseFactory object. - *

- * The specified task will be executed on the {@link #executor() callback - * executor}. - * - * @param The value type associated with the returned Promise. - * @param task The task whose result will be available from the returned - * Promise. - * @return A new Promise that will hold the result of the specified task. - */ - public Promise submit(Callable< ? extends T> task) { - DeferredPromiseImpl promise = new DeferredPromiseImpl<>(this); - Runnable submit = promise.new Submit(task); - try { - executor().execute(submit); - } catch (Exception t) { - promise.tryResolve(null, t); - } - return promise.orDone(); - } - - /** - * Returns a new Promise that is a latch on the resolution of the specified - * Promises. - *

- * The returned Promise uses the callback executor and scheduled executor of - * this PromiseFactory object. - *

- * The returned Promise acts as a gate and must be resolved after all of the - * specified Promises are resolved. - * - * @param The value type of the List value associated with the returned - * Promise. - * @param A subtype of the value type of the List value associated with - * the returned Promise. - * @param promises The Promises which must be resolved before the returned - * Promise must be resolved. Must not be {@code null} and all of - * the elements in the collection must not be {@code null}. - * @return A Promise that must be successfully resolved with a List of the - * values in the order of the specified Promises if all the - * specified Promises are successfully resolved. The List in the - * returned Promise is the property of the caller and is modifiable. - * The returned Promise must be resolved with a failure of - * {@link FailedPromisesException} if any of the specified Promises - * are resolved with a failure. The failure - * {@link FailedPromisesException} must contain all of the specified - * Promises which resolved with a failure. - */ - public Promise> all( - Collection> promises) { - if (promises.isEmpty()) { - List value = new ArrayList<>(); - return resolved(value); - } - - /* make a copy and capture the ordering */ - List> list = new ArrayList<>(promises); - - DeferredPromiseImpl> chained = new DeferredPromiseImpl<>(this); - All all = new All<>(chained, list); - for (Promise p : list) { - p.onResolve(all); - } - return chained.orDone(); - } - - /** - * A callback used to resolve the specified Promise when the specified list - * of Promises are resolved for the {@link PromiseFactory#all(Collection)} - * method. - * - * @ThreadSafe - */ - private static final class All implements Runnable { - private final DeferredPromiseImpl> chained; - private final List> promises; - private final AtomicInteger promiseCount; - - All(DeferredPromiseImpl> chained, List> promises) { - this.chained = requireNonNull(chained); - this.promises = requireNonNull(promises); - this.promiseCount = new AtomicInteger(promises.size()); - } - - @Override - public void run() { - if (promiseCount.decrementAndGet() != 0) { - return; - } - List value = new ArrayList<>(promises.size()); - List> failed = new ArrayList<>(promises.size()); - Throwable cause = null; - for (Promise p : promises) { - Result result = PromiseImpl.collect(p); - if (result.fail != null) { - failed.add(p); - if (cause == null) { - cause = result.fail; - } - } else { - value.add(result.value); - } - } - if (failed.isEmpty()) { - chained.tryResolve(value, null); - } else { - chained.tryResolve(null, - new FailedPromisesException(failed, cause)); - } - } - } - - /** - * Returns an Executor implementation that executes tasks immediately on the - * thread calling the {@code Executor.execute} method. - * - * @return An Executor implementation that executes tasks immediately on the - * thread calling the {@code Executor.execute} method. - */ - public static Executor inlineExecutor() { - return new InlineExecutor(); - } - - boolean allowCurrentThread() { - return allowCurrentThread; - } - - /** - * An Executor implementation which executes the task immediately on the - * thread calling the {@code Executor.execute} method. - * - * @Immutable - */ - private static final class InlineExecutor implements Executor { - InlineExecutor() {} - - @Override - public void execute(Runnable callback) { - callback.run(); - } - } - - /** - * Default executors for Promises. - * - * @Immutable - */ - private static final class DefaultExecutors - implements ThreadFactory, RejectedExecutionHandler, Runnable { - private static final DefaultExecutors callbacks; - private static final ScheduledExecutor scheduledExecutor; - private static final ThreadPoolExecutor callbackExecutor; - static { - callbacks = new DefaultExecutors(); - scheduledExecutor = new ScheduledExecutor(2, callbacks); - callbackExecutor = new ThreadPoolExecutor(0, 64, 60L, - TimeUnit.SECONDS, new SynchronousQueue<>(), callbacks, callbacks); - } - - static Executor callbackExecutor() { - return callbackExecutor; - } - - static ScheduledExecutorService scheduledExecutor() { - return scheduledExecutor; - } - - private final AtomicBoolean shutdownHookInstalled; - private final ThreadFactory delegateThreadFactory; - - private DefaultExecutors() { - shutdownHookInstalled = new AtomicBoolean(); - delegateThreadFactory = Executors.defaultThreadFactory(); - } - - /** - * Executor threads should not prevent VM from exiting. - */ - @Override - public Thread newThread(Runnable r) { - if (shutdownHookInstalled.compareAndSet(false, true)) { - Thread shutdownThread = delegateThreadFactory.newThread(this); - shutdownThread.setName( - "ExecutorShutdownHook," + shutdownThread.getName()); - try { - Runtime.getRuntime().addShutdownHook(shutdownThread); - } catch (IllegalStateException e) { - // VM is already shutting down... - callbackExecutor.shutdown(); - scheduledExecutor.shutdown(); - } - } - Thread t = delegateThreadFactory.newThread(r); - t.setName("PromiseFactory," + t.getName()); - t.setDaemon(true); - return t; - } - - /** - * Call the callback using the caller's thread because the thread pool - * rejected the execution. - */ - @Override - public void rejectedExecution(Runnable callback, - ThreadPoolExecutor executor) { - try { - callback.run(); - } catch (Throwable t) { - uncaughtException(t); - } - } - - /** - * Shutdown hook - */ - @Override - public void run() { - // limit new thread creation - callbackExecutor.setMaximumPoolSize( - Math.max(1, callbackExecutor.getPoolSize())); - // Run all delayed callbacks now - scheduledExecutor.shutdown(); - BlockingQueue queue = scheduledExecutor.getQueue(); - if (!queue.isEmpty()) { - for (Object r : queue.toArray()) { - if (r instanceof RunnableScheduledFuture< ? >) { - RunnableScheduledFuture< ? > future = (RunnableScheduledFuture< ? >) r; - if ((future.getDelay(TimeUnit.NANOSECONDS) > 0L) - && queue.remove(future)) { - future.run(); - scheduledExecutor.afterExecute(future, null); - } - } - } - scheduledExecutor.shutdown(); - } - try { - scheduledExecutor.awaitTermination(20, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - // Shutdown callback executor - callbackExecutor.shutdown(); - try { - callbackExecutor.awaitTermination(20, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - /** - * ScheduledThreadPoolExecutor for scheduled execution. - * - * @ThreadSafe - */ - private static final class ScheduledExecutor - extends ScheduledThreadPoolExecutor { - ScheduledExecutor(int corePoolSize, ThreadFactory threadFactory) { - super(corePoolSize, threadFactory); - } - - /** - * Handle uncaught exceptions - */ - @Override - protected void afterExecute(Runnable r, Throwable t) { - super.afterExecute(r, t); - if ((t == null) && (r instanceof Future< ? >)) { - boolean interrupted = Thread.interrupted(); - try { - ((Future< ? >) r).get(); - } catch (CancellationException e) { - // ignore - } catch (InterruptedException e) { - interrupted = true; - } catch (ExecutionException e) { - t = e.getCause(); - } finally { - if (interrupted) { // restore interrupt status - Thread.currentThread().interrupt(); - } - } - } - if (t != null) { - uncaughtException(t); - } - } - } - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/PromiseImpl.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/PromiseImpl.java deleted file mode 100644 index b8c475de1..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/PromiseImpl.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2021). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static java.util.Objects.requireNonNull; - -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.osgi.util.function.Consumer; -import org.osgi.util.function.Function; -import org.osgi.util.function.Predicate; - -/** - * Abstract Promise implementation. - *

- * This class is not used directly by clients. Clients should use - * {@link PromiseFactory} to create a {@link Promise}. - * - * @param The result type associated with the Promise. - * @ThreadSafe - * @author $Id$ - */ -abstract class PromiseImpl implements Promise { - /** - * The factory to use for callbacks and scheduled operations. - */ - private final PromiseFactory factory; - /** - * A ConcurrentLinkedQueue to hold the callbacks for this Promise, so no - * additional synchronization is required to write to or read from the - * queue. - */ - private final ConcurrentLinkedQueue callbacks; - - /** - * Initialize this Promise. - * - * @param factory The factory to use for callbacks and scheduled - * operations. - */ - PromiseImpl(PromiseFactory factory) { - this.factory = requireNonNull(factory); - callbacks = new ConcurrentLinkedQueue<>(); - } - - /** - * Return a new {@link DeferredPromiseImpl} using the {@link PromiseFactory} - * of this PromiseImpl. - * - * @return A new DeferredPromiseImpl. - * @since 1.1 - */ - DeferredPromiseImpl deferred() { - return new DeferredPromiseImpl<>(factory); - } - - /** - * Return a new {@link ResolvedPromiseImpl} using the {@link PromiseFactory} - * of this PromiseImpl. - * - * @param v Value for the ResolvedPromiseImpl. - * @return A new ResolvedPromiseImpl. - * @since 1.1 - */ - ResolvedPromiseImpl resolved(V v) { - return new ResolvedPromiseImpl<>(v, factory); - } - - /** - * Return a new {@link FailedPromiseImpl} using the {@link PromiseFactory} - * of this PromiseImpl. - * - * @param f Failure for the FailedPromiseImpl. - * @return A new FailedPromiseImpl. - * @since 1.1 - */ - FailedPromiseImpl failed(Throwable f) { - return new FailedPromiseImpl<>(f, factory); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise onResolve(Runnable callback) { - requireNonNull(callback); - if (factory.allowCurrentThread() && isDone()) { - try { - callback.run(); - } catch (Throwable t) { - uncaughtException(t); - } - } else { - callbacks.offer(callback); - notifyCallbacks(); // call any registered callbacks - } - return this; - } - - /** - * Call any registered callbacks if this Promise is resolved. - */ - void notifyCallbacks() { - if (!isDone()) { - return; // return if not resolved - } - /* - * Note: multiple threads can be in this method removing callbacks from - * the queue and executing them, so the order in which callbacks are - * executed cannot be specified. - */ - for (Runnable callback = callbacks.poll(); callback != null; callback = callbacks.poll()) { - try { - try { - factory.executor().execute(callback); - } catch (RejectedExecutionException e) { - callback.run(); - } - } catch (Throwable t) { - uncaughtException(t); - } - } - } - - /** - * Schedule a operation on the scheduled executor. - * - * @since 1.1 - */ - ScheduledFuture< ? > schedule(Runnable operation, long delay, - TimeUnit unit) { - try { - try { - return factory.scheduledExecutor().schedule(operation, delay, - unit); - } catch (RejectedExecutionException e) { - operation.run(); - } - } catch (Throwable t) { - uncaughtException(t); - } - return null; - } - - /** - * Handle an uncaught exception from a Runnable. - * - * @param t The uncaught exception. - * @since 1.1 - */ - static void uncaughtException(Throwable t) { - try { - Thread thread = Thread.currentThread(); - thread.getUncaughtExceptionHandler().uncaughtException(thread, t); - } catch (Throwable ignored) { - // we ignore this - } - } - - /** - * {@inheritDoc} - */ - @Override - public Promise onSuccess(Consumer< ? super T> success) { - return onResolve(new OnSuccess(success)); - } - - /** - * A callback used for the {@link #onSuccess(Consumer)} method. - * - * @Immutable - * @since 1.1 - */ - private final class OnSuccess implements Runnable { - private final Consumer< ? super T> success; - - OnSuccess(Consumer< ? super T> success) { - this.success = requireNonNull(success); - } - - @Override - public void run() { - Result result = collect(); - if (result.fail == null) { - try { - success.accept(result.value); - } catch (Throwable e) { - uncaughtException(e); - } - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public Promise onFailure(Consumer< ? super Throwable> failure) { - return onResolve(new OnFailure(failure)); - } - - /** - * A callback used for the {@link #onFailure(Consumer)} method. - * - * @Immutable - * @since 1.1 - */ - private final class OnFailure implements Runnable { - private final Consumer< ? super Throwable> failure; - - OnFailure(Consumer< ? super Throwable> failure) { - this.failure = requireNonNull(failure); - } - - @Override - public void run() { - Result result = collect(); - if (result.fail != null) { - try { - failure.accept(result.fail); - } catch (Throwable e) { - uncaughtException(e); - } - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public Promise then(Success success, Failure failure) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new Then<>(this, success, failure)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise then(Success success) { - return then(success, null); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise thenAccept(Consumer< ? super T> consumer) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new ThenAccept(this, consumer)); - return chained.orDone(); - } - - - /** - * {@inheritDoc} - */ - @Override - public Promise filter(Predicate predicate) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new Filter(this, predicate)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise map(Function mapper) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new Map<>(this, mapper)); - return chained.orDone(); - } - - - /** - * {@inheritDoc} - */ - @Override - public Promise flatMap(Function> mapper) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new FlatMap<>(this, mapper)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise recover(Function, ? extends T> recovery) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new Recover(this, recovery)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise recoverWith(Function, Promise> recovery) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new RecoverWith(this, recovery)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise fallbackTo(Promise fallback) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new FallbackTo(this, fallback)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise timeout(long millis) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new Timeout(this, millis)); - return chained.orDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise delay(long millis) { - DeferredPromiseImpl chained = deferred(); - onResolve(chained.new Delay(this, millis)); - return chained.orDone(); - } - - /** - * A holder of the result of a Promise. - * - * @NotThreadSafe - * @since 1.1 - */ - static final class Result

{ - P value; - Throwable fail; - - Result(P value) { - this.value = value; - this.fail = null; - } - - Result(Throwable fail) { - this.value = null; - this.fail = fail; - } - } - - /** - * Return a holder of the result of this PromiseImpl. - * - * @since 1.1 - */ - abstract Result collect(); - - /** - * Return a holder of the result of the specified Promise. - * - * @since 1.1 - */ - static Result collect(Promise< ? extends R> promise) { - if (promise instanceof PromiseImpl) { - @SuppressWarnings("unchecked") - PromiseImpl impl = (PromiseImpl) promise; - return impl.collect(); - } - if (!promise.isDone()) { - return new Result<>(new AssertionError("promise not resolved")); - } - final boolean interrupted = Thread.interrupted(); - try { - Throwable fail = promise.getFailure(); - if (fail == null) { - return new Result<>(promise.getValue()); - } - return new Result<>(fail); - } catch (Throwable e) { - return new Result<>(e); // propagate new exception - } finally { - if (interrupted) { // restore interrupt status - Thread.currentThread().interrupt(); - } - } - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java deleted file mode 100644 index 650a2b0e2..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2017). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static org.osgi.util.promise.PromiseFactory.defaultFactory; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -/** - * Static helper methods for {@link Promise}s. - *

- * These methods return Promises which use the default callback executor and - * default scheduled executor. See {@link PromiseFactory} for similar methods - * which use executors other than the default executors. - * - * @ThreadSafe - * @see PromiseFactory - * @author $Id$ - */ -public class Promises { - private Promises() { - // disallow object creation - } - - /** - * Returns a new Promise that has been resolved with the specified value. - * - * @param The value type associated with the returned Promise. - * @param value The value of the resolved Promise. - * @return A new Promise which uses the default callback executor and - * default scheduled executor that has been resolved with the - * specified value. - * @see PromiseFactory#resolved(Object) - */ - public static Promise resolved(T value) { - return defaultFactory.resolved(value); - } - - /** - * Returns a new Promise that has been resolved with the specified failure. - * - * @param The value type associated with the returned Promise. - * @param failure The failure of the resolved Promise. Must not be - * {@code null}. - * @return A new Promise which uses the default callback executor and - * default scheduled executor that has been resolved with the - * specified failure. - * @see PromiseFactory#failed(Throwable) - */ - public static Promise failed(Throwable failure) { - return defaultFactory.failed(failure); - } - - /** - * Returns a new Promise that is a latch on the resolution of the specified - * Promises. - *

- * The returned Promise acts as a gate and must be resolved after all of the - * specified Promises are resolved. - * - * @param The value type of the List value associated with the returned - * Promise. - * @param A subtype of the value type of the List value associated with - * the returned Promise. - * @param promises The Promises which must be resolved before the returned - * Promise must be resolved. Must not be {@code null} and all of - * the elements in the collection must not be {@code null}. - * @return A Promise which uses the default callback executor and default - * scheduled executor that is resolved only when all the specified - * Promises are resolved. The returned Promise must be successfully - * resolved with a List of the values in the order of the specified - * Promises if all the specified Promises are successfully resolved. - * The List in the returned Promise is the property of the caller - * and is modifiable. The returned Promise must be resolved with a - * failure of {@link FailedPromisesException} if any of the - * specified Promises are resolved with a failure. The failure - * {@link FailedPromisesException} must contain all of the specified - * Promises which resolved with a failure. - * @see PromiseFactory#all(Collection) - */ - public static Promise> all( - Collection> promises) { - return defaultFactory.all(promises); - } - - /** - * Returns a new Promise that is a latch on the resolution of the specified - * Promises. - *

- * The new Promise acts as a gate and must be resolved after all of the - * specified Promises are resolved. - * - * @param The value type associated with the specified Promises. - * @param promises The Promises which must be resolved before the returned - * Promise must be resolved. Must not be {@code null} and all of - * the arguments must not be {@code null}. - * @return A Promise which uses the default callback executor and scheduled - * executor that is resolved only when all the specified Promises - * are resolved. The returned Promise must be successfully resolved - * with a List of the values in the order of the specified Promises - * if all the specified Promises are successfully resolved. The List - * in the returned Promise is the property of the caller and is - * modifiable. The returned Promise must be resolved with a failure - * of {@link FailedPromisesException} if any of the specified - * Promises are resolved with a failure. The failure - * {@link FailedPromisesException} must contain all of the specified - * Promises which resolved with a failure. - * @see PromiseFactory#all(Collection) - */ - @SafeVarargs - public static Promise> all(Promise... promises) { - @SuppressWarnings("unchecked") - List> list = Arrays.asList((Promise[]) promises); - return defaultFactory.all(list); - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/ResolvedPromiseImpl.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/ResolvedPromiseImpl.java deleted file mode 100644 index 70fbc3f39..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/ResolvedPromiseImpl.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2017, 2021). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import static java.util.Objects.requireNonNull; - -import org.osgi.util.function.Consumer; -import org.osgi.util.function.Function; - -/** - * Resolved Promise implementation. - *

- * This class is not used directly by clients. Clients should use - * {@link PromiseFactory#resolved(Object)} to create a resolved {@link Promise}. - * - * @param The result type associated with the Promise. - * @since 1.1 - * @ThreadSafe - * @author $Id$ - */ -final class ResolvedPromiseImpl extends PromiseImpl { - /** - * The value of this resolved Promise. - */ - private final T value; - - /** - * Initialize this resolved Promise. - * - * @param value The value of this resolved Promise. - * @param factory The factory to use for callbacks and scheduled operations. - */ - ResolvedPromiseImpl(T value, PromiseFactory factory) { - super(factory); - this.value = value; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isDone() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public T getValue() { - return value; - } - - /** - * {@inheritDoc} - */ - @Override - public Throwable getFailure() { - return null; - } - - /** - * {@inheritDoc} - */ - @Override - Result collect() { - return new Result<>(value); - } - - @Override - public String toString() { - return super.toString() + "[resolved: " + value + "]"; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise onFailure(Consumer< ? super Throwable> failure) { - requireNonNull(failure); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise then(Success< ? super T, ? extends R> success, - Failure failure) { - if (success == null) { - return resolved(null); - } - return super.then(success, failure); - } - - /** - * {@inheritDoc} - */ - @Override - public Promise recover(Function, ? extends T> recovery) { - requireNonNull(recovery); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise recoverWith( - Function,Promise< ? extends T>> recovery) { - requireNonNull(recovery); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise fallbackTo(Promise< ? extends T> fallback) { - requireNonNull(fallback); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Promise timeout(long millis) { - return this; - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Success.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Success.java deleted file mode 100644 index cedefa1a5..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Success.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2015). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -import org.osgi.annotation.versioning.ConsumerType; - -/** - * Success callback for a Promise. - * - *

- * A Success callback is registered with a {@link Promise} using the - * {@link Promise#then(Success)} method and is called if the Promise is resolved - * successfully. - * - *

- * This is a functional interface and can be used as the assignment target for a - * lambda expression or method reference. - * - * @param The value type of the resolved Promise passed as input to this - * callback. - * @param The value type of the returned Promise from this callback. - * - * @ThreadSafe - * @author $Id$ - */ -@ConsumerType -@FunctionalInterface -public interface Success { - /** - * Success callback for a Promise. - * - *

- * This method is called if the Promise with which it is registered resolves - * successfully. - * - *

- * In the remainder of this description we will refer to the Promise - * returned by this method as the returned Promise and the Promise returned - * by {@link Promise#then(Success)} when this Success callback was - * registered as the chained Promise. - * - *

- * If the returned Promise is {@code null} then the chained Promise must - * resolve immediately with a successful value of {@code null}. If the - * returned Promise is not {@code null} then the chained Promise must be - * resolved when the returned Promise is resolved. - * - * @param resolved The successfully resolved {@link Promise}. - * @return The Promise to use to resolve the chained Promise, or - * {@code null} if the chained Promise is to be resolved immediately - * with the value {@code null}. - * @throws Exception The chained Promise must be failed with the thrown - * exception. - */ - Promise call(Promise resolved) throws Exception; -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/TimeoutException.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/TimeoutException.java deleted file mode 100644 index 09186f552..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/TimeoutException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.promise; - -/** - * Timeout exception for a Promise. - * - * @since 1.1 - * @author $Id$ - */ -public class TimeoutException extends Exception { - private static final long serialVersionUID = 1L; - - /** - * Create a new {@code TimeoutException}. - */ - public TimeoutException() { - super(); - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/package-info.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/package-info.java deleted file mode 100644 index 1dde8192b..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/package-info.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2014, 2018). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Promise Package Version 1.1. - *

- * Bundles wishing to use this package must list the package in the - * Import-Package header of the bundle's manifest. - *

- * Example import for consumers using the API in this package: - *

- * {@code Import-Package: org.osgi.util.promise; version="[1.1,2.0)"} - *

- * Example import for providers implementing the API in this package: - *

- * {@code Import-Package: org.osgi.util.promise; version="[1.1,1.2)"} - * - * @author $Id$ - */ - -@Version("1.1.1") -package org.osgi.util.promise; - -import org.osgi.annotation.versioning.Version; - diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/xml/XMLParserActivator.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/xml/XMLParserActivator.java deleted file mode 100644 index cad340e74..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/xml/XMLParserActivator.java +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2002, 2021). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.osgi.util.xml; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.FactoryConfigurationError; -import javax.xml.parsers.SAXParserFactory; - -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.ServiceFactory; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; - -/** - * A BundleActivator class that allows any JAXP compliant XML Parser to register - * itself as an OSGi parser service. - * - * Multiple JAXP compliant parsers can concurrently register by using this - * BundleActivator class. Bundles who wish to use an XML parser can then use the - * framework's service registry to locate available XML Parsers with the desired - * characteristics such as validating and namespace-aware. - * - *

- * The services that this bundle activator enables a bundle to provide are: - *

    - *
  • {@code javax.xml.parsers.SAXParserFactory}({@link #SAXFACTORYNAME})
  • - *
  • {@code javax.xml.parsers.DocumentBuilderFactory}( {@link #DOMFACTORYNAME} - * )
  • - *
- * - *

- * The algorithm to find the implementations of the abstract parsers is derived - * from the JAR file specifications, specifically the Services API. - *

- * An XMLParserActivator assumes that it can find the class file names of the - * factory classes in the following files: - *

    - *
  • {@code /META-INF/services/javax.xml.parsers.SAXParserFactory} is a file - * contained in a jar available to the runtime which contains the implementation - * class name(s) of the SAXParserFactory.
  • - *
  • {@code /META-INF/services/javax.xml.parsers.DocumentBuilderFactory} is a - * file contained in a jar available to the runtime which contains the - * implementation class name(s) of the {@code DocumentBuilderFactory}
  • - *
- *

- * If either of the files does not exist, {@code XMLParserActivator} assumes - * that the parser does not support that parser type. - * - *

- * {@code XMLParserActivator} attempts to instantiate both the - * {@code SAXParserFactory} and the {@code DocumentBuilderFactory}. It registers - * each factory with the framework along with service properties: - *

    - *
  • {@link #PARSER_VALIDATING}- indicates if this factory supports validating - * parsers. It's value is a {@code Boolean}.
  • - *
  • {@link #PARSER_NAMESPACEAWARE}- indicates if this factory supports - * namespace aware parsers It's value is a {@code Boolean}.
  • - *
- *

- * Individual parser implementations may have additional features, properties, - * or attributes which could be used to select a parser with a filter. These can - * be added by extending this class and overriding the {@code setSAXProperties} - * and {@code setDOMProperties} methods. - * - * @ThreadSafe - * @author $Id$ - */ -public class XMLParserActivator implements BundleActivator, ServiceFactory { - /** Context of this bundle */ - private volatile BundleContext bundleContext; - /** - * Filename containing the SAX Parser Factory Class name. Also used as the - * basis for the {@code SERVICE_PID} registration property. - */ - public static final String SAXFACTORYNAME = "javax.xml.parsers.SAXParserFactory"; - /** - * Filename containing the DOM Parser Factory Class name. Also used as the - * basis for the {@code SERVICE_PID} registration property. - */ - public static final String DOMFACTORYNAME = "javax.xml.parsers.DocumentBuilderFactory"; - /** Path to the factory class name files */ - private static final String PARSERCLASSFILEPATH = "/META-INF/services/"; - /** Fully qualified path name of SAX Parser Factory Class Name file */ - public static final String SAXCLASSFILE = PARSERCLASSFILEPATH + SAXFACTORYNAME; - /** Fully qualified path name of DOM Parser Factory Class Name file */ - public static final String DOMCLASSFILE = PARSERCLASSFILEPATH + DOMFACTORYNAME; - /** SAX Factory Service Description */ - private static final String SAXFACTORYDESCRIPTION = "A JAXP Compliant SAX Parser"; - /** DOM Factory Service Description */ - private static final String DOMFACTORYDESCRIPTION = "A JAXP Compliant DOM Parser"; - /** - * Service property specifying if factory is configured to support - * validating parsers. The value is of type {@code Boolean}. - */ - public static final String PARSER_VALIDATING = "parser.validating"; - /** - * Service property specifying if factory is configured to support namespace - * aware parsers. The value is of type {@code Boolean}. - */ - public static final String PARSER_NAMESPACEAWARE = "parser.namespaceAware"; - /** - * Key for parser factory name property - this must be saved in the parsers - * properties hashtable so that the parser factory can be instantiated from - * a ServiceReference - */ - private static final String FACTORYNAMEKEY = "parser.factoryname"; - - /** - * Called when this bundle is started so the Framework can perform the - * bundle-specific activities necessary to start this bundle. This method - * can be used to register services or to allocate any resources that this - * bundle needs. - * - *

- * This method must complete and return to its caller in a timely manner. - * - *

- * This method attempts to register a SAX and DOM parser with the - * Framework's service registry. - * - * @param context The execution context of the bundle being started. - * @throws java.lang.Exception If this method throws an exception, this - * bundle is marked as stopped and the Framework will remove this - * bundle's listeners, unregister all services registered by this - * bundle, and release all services used by this bundle. - */ - @Override - public void start(BundleContext context) throws Exception { - this.bundleContext = context; - Bundle parserBundle = context.getBundle(); - // check for sax parsers - registerSAXParsers(getParserFactoryClassNames(parserBundle.getResource(SAXCLASSFILE))); - // check for dom parsers - registerDOMParsers(getParserFactoryClassNames(parserBundle.getResource(DOMCLASSFILE))); - } - - /** - * This method has nothing to do as all active service registrations will - * automatically get unregistered when the bundle stops. - * - * @param context The execution context of the bundle being stopped. - * @throws java.lang.Exception If this method throws an exception, the - * bundle is still marked as stopped, and the Framework will remove - * the bundle's listeners, unregister all services registered by the - * bundle, and release all services used by the bundle. - */ - @Override - public void stop(BundleContext context) throws Exception { - // framework will automatically unregister the parser services - } - - /** - * Given the URL for a file, reads and returns the parser class names. There - * may be multiple classes specified in this file, one per line. There may - * also be comment lines in the file, which begin with "#". - * - * @param parserUrl The URL of the service file containing the parser class - * names - * @return A List of strings containing the parser class names. - * @throws IOException if there is a problem reading the URL input stream - */ - private List getParserFactoryClassNames(URL parserUrl) throws IOException { - if (parserUrl == null) { - return Collections.emptyList(); - } - List v = new ArrayList<>(1); - String parserFactoryClassName = null; - InputStream is = parserUrl.openStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(is)); - while (true) { - parserFactoryClassName = br.readLine(); - if (parserFactoryClassName == null) { - break; // end of file reached - } - String pfcName = parserFactoryClassName.trim(); - if (pfcName.length() == 0) { - continue; // blank line - } - int commentIdx = pfcName.indexOf("#"); - if (commentIdx == 0) { // comment line - continue; - } else - if (commentIdx < 0) { // no comment on this line - v.add(pfcName); - } else { - v.add(pfcName.substring(0, commentIdx).trim()); - } - } - return v; - } - - /** - * Register SAX Parser Factory Services with the framework. - * - * @param parserFactoryClassNames - a {@code List} of {@code String} objects - * containing the names of the parser Factory Classes - * @throws FactoryConfigurationError if thrown from {@code getFactory} - */ - private void registerSAXParsers(List parserFactoryClassNames) throws FactoryConfigurationError { - Iterator e = parserFactoryClassNames.iterator(); - int index = 0; - while (e.hasNext()) { - String parserFactoryClassName = e.next(); - // create a sax parser factory just to get it's default - // properties. It will never be used since - // this class will operate as a service factory and give each - // service requestor it's own SaxParserFactory - SAXParserFactory factory = (SAXParserFactory) getFactory(parserFactoryClassName); - Hashtable properties = new Hashtable<>(7); - // figure out the default properties of the parser - setDefaultSAXProperties(factory, properties, index); - // store the parser factory class name in the properties so that - // it can be retrieved when getService is called - // to return a parser factory - properties.put(FACTORYNAMEKEY, parserFactoryClassName); - // register the factory as a service - bundleContext.registerService(SAXFACTORYNAME, this, properties); - index++; - } - } - - /** - *

- * Set the SAX Parser Service Properties. By default, the following - * properties are set: - *

    - *
  • {@code SERVICE_DESCRIPTION}
  • - *
  • {@code SERVICE_PID}
  • - *
  • {@code PARSER_VALIDATING}- instantiates a parser and queries it to - * find out whether it is validating or not
  • - *
  • {@code PARSER_NAMESPACEAWARE}- instantiates a parser and queries it - * to find out whether it is namespace aware or not
  • - *
      - * - * @param factory The {@code SAXParserFactory} object - * @param props {@code Hashtable} of service properties. - */ - private void setDefaultSAXProperties(SAXParserFactory factory, Hashtable props, int index) { - props.put(Constants.SERVICE_DESCRIPTION, SAXFACTORYDESCRIPTION); - props.put(Constants.SERVICE_PID, SAXFACTORYNAME + "." + bundleContext.getBundle().getBundleId() + "." + index); - setSAXProperties(factory, props); - } - - /** - *

      - * Set the customizable SAX Parser Service Properties. - * - *

      - * This method attempts to instantiate a validating parser and a namespace - * aware parser to determine if the parser can support those features. The - * appropriate properties are then set in the specified properties object. - * - *

      - * This method can be overridden to add additional SAX2 features and - * properties. If you want to be able to filter searches of the OSGi service - * registry, this method must put a key, value pair into the properties - * object for each feature or property. For example, - * - * properties.put("http://www.acme.com/features/foo", Boolean.TRUE); - * - * @param factory - the SAXParserFactory object - * @param properties - the properties object for the service - */ - public void setSAXProperties(SAXParserFactory factory, Hashtable properties) { - // check if this parser can be configured to validate - boolean validating = true; - factory.setValidating(true); - factory.setNamespaceAware(false); - try { - factory.newSAXParser(); - } catch (Exception pce_val) { - validating = false; - } - // check if this parser can be configured to be namespaceaware - boolean namespaceaware = true; - factory.setValidating(false); - factory.setNamespaceAware(true); - try { - factory.newSAXParser(); - } catch (Exception pce_nsa) { - namespaceaware = false; - } - // set the factory values - factory.setValidating(validating); - factory.setNamespaceAware(namespaceaware); - // set the OSGi service properties - properties.put(PARSER_NAMESPACEAWARE, Boolean.valueOf(namespaceaware)); - properties.put(PARSER_VALIDATING, Boolean.valueOf(validating)); - } - - /** - * Register DOM Parser Factory Services with the framework. - * - * @param parserFactoryClassNames - a {@code List} of {@code String} objects - * containing the names of the parser Factory Classes - * @throws FactoryConfigurationError if thrown from {@code getFactory} - */ - private void registerDOMParsers(List parserFactoryClassNames) throws FactoryConfigurationError { - Iterator e = parserFactoryClassNames.iterator(); - int index = 0; - while (e.hasNext()) { - String parserFactoryClassName = e.next(); - // create a dom parser factory just to get it's default - // properties. It will never be used since - // this class will operate as a service factory and give each - // service requestor it's own DocumentBuilderFactory - DocumentBuilderFactory factory = (DocumentBuilderFactory) getFactory(parserFactoryClassName); - Hashtable properties = new Hashtable<>(7); - // figure out the default properties of the parser - setDefaultDOMProperties(factory, properties, index); - // store the parser factory class name in the properties so that - // it can be retrieved when getService is called - // to return a parser factory - properties.put(FACTORYNAMEKEY, parserFactoryClassName); - // register the factory as a service - bundleContext.registerService(DOMFACTORYNAME, this, properties); - index++; - } - } - - /** - * Set the DOM parser service properties. - * - * By default, the following properties are set: - *

        - *
      • {@code SERVICE_DESCRIPTION}
      • - *
      • {@code SERVICE_PID}
      • - *
      • {@code PARSER_VALIDATING}
      • - *
      • {@code PARSER_NAMESPACEAWARE}
      • - *
          - * - * @param factory The {@code DocumentBuilderFactory} object - * @param props {@code Hashtable} of service properties. - */ - private void setDefaultDOMProperties(DocumentBuilderFactory factory, Hashtable props, int index) { - props.put(Constants.SERVICE_DESCRIPTION, DOMFACTORYDESCRIPTION); - props.put(Constants.SERVICE_PID, DOMFACTORYNAME + "." + bundleContext.getBundle().getBundleId() + "." + index); - setDOMProperties(factory, props); - } - - /** - *

          - * Set the customizable DOM Parser Service Properties. - * - *

          - * This method attempts to instantiate a validating parser and a namespace - * aware parser to determine if the parser can support those features. The - * appropriate properties are then set in the specified props object. - * - *

          - * This method can be overridden to add additional DOM2 features and - * properties. If you want to be able to filter searches of the OSGi service - * registry, this method must put a key, value pair into the properties - * object for each feature or property. For example, - * - * properties.put("http://www.acme.com/features/foo", Boolean.TRUE); - * - * @param factory - the DocumentBuilderFactory object - * @param props - Hashtable of service properties. - */ - public void setDOMProperties(DocumentBuilderFactory factory, Hashtable props) { - // check if this parser can be configured to validate - boolean validating = true; - factory.setValidating(true); - factory.setNamespaceAware(false); - try { - factory.newDocumentBuilder(); - } catch (Exception pce_val) { - validating = false; - } - // check if this parser can be configured to be namespaceaware - boolean namespaceaware = true; - factory.setValidating(false); - factory.setNamespaceAware(true); - try { - factory.newDocumentBuilder(); - } catch (Exception pce_nsa) { - namespaceaware = false; - } - // set the factory values - factory.setValidating(validating); - factory.setNamespaceAware(namespaceaware); - // set the OSGi service properties - props.put(PARSER_VALIDATING, Boolean.valueOf(validating)); - props.put(PARSER_NAMESPACEAWARE, Boolean.valueOf(namespaceaware)); - } - - /** - * Given a parser factory class name, instantiate that class. - * - * @param parserFactoryClassName A {@code String} object containing the name - * of the parser factory class - * @return a parserFactoryClass Object - * @pre parserFactoryClassName!=null - */ - private Object getFactory(String parserFactoryClassName) throws FactoryConfigurationError { - try { - return bundleContext.getBundle() - .loadClass(parserFactoryClassName) - .getConstructor() - .newInstance(); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new FactoryConfigurationError(e); - } - } - - /** - * Creates a new XML Parser Factory object. - * - *

          - * A unique XML Parser Factory object is returned for each call to this - * method. - * - *

          - * The returned XML Parser Factory object will be configured for validating - * and namespace aware support as specified in the service properties of the - * specified ServiceRegistration object. - * - * This method can be overridden to configure additional features in the - * returned XML Parser Factory object. - * - * @param bundle The bundle using the service. - * @param registration The {@code ServiceRegistration} object for the - * service. - * @return A new, configured XML Parser Factory object or null if a - * configuration error was encountered - */ - @Override - public Object getService(Bundle bundle, ServiceRegistration registration) { - ServiceReference sref = registration.getReference(); - String parserFactoryClassName = (String) sref.getProperty(FACTORYNAMEKEY); - // need to set factory properties - Object factory = getFactory(parserFactoryClassName); - if (factory instanceof SAXParserFactory) { - ((SAXParserFactory) factory).setValidating(((Boolean) sref.getProperty(PARSER_VALIDATING)).booleanValue()); - ((SAXParserFactory) factory).setNamespaceAware(((Boolean) sref.getProperty(PARSER_NAMESPACEAWARE)).booleanValue()); - } else { - if (factory instanceof DocumentBuilderFactory) { - ((DocumentBuilderFactory) factory).setValidating(((Boolean) sref.getProperty(PARSER_VALIDATING)).booleanValue()); - ((DocumentBuilderFactory) factory).setNamespaceAware(((Boolean) sref.getProperty(PARSER_NAMESPACEAWARE)).booleanValue()); - } - } - return factory; - } - - /** - * Releases a XML Parser Factory object. - * - * @param bundle The bundle releasing the service. - * @param registration The {@code ServiceRegistration} object for the - * service. - * @param service The XML Parser Factory object returned by a previous call - * to the {@code getService} method. - */ - @Override - public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) { - // nothing to do - } -} diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/xml/package-info.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/xml/package-info.java deleted file mode 100644 index 1f05ed780..000000000 --- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/xml/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * XML Parser Package Version 1.0. - * - *

          - * Bundles wishing to use this package must list the package in the - * Import-Package header of the bundle's manifest. - * - *

          - * Example import for consumers using the API in this package: - *

          - * {@code Import-Package: org.osgi.util.xml; version="[1.0,2.0)"} - * - * @author $Id$ - */ - -@Version("1.0.1") -package org.osgi.util.xml; - -import org.osgi.annotation.versioning.Version;