OperationBuilder.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.ge.operations;
import java.util.function.Function;
import java.util.function.Supplier;
import org.eclipse.emf.ecore.EObject;
/**
* Builder uses for creating operations. This class is not a builder pattern in the sense of the builder pattern. It does not create an {@link Operation}.
*
* This interface is used in conjunction with {@link Operation#createWithBuilder(java.util.function.Consumer)} to create the operation.
* Each call to an operation builder creates a step in the resulting operation. Multiple calls to the same instance will
* result in multiple branches in the operation.
*
* For simple operations, {@link Operation} defines other methods to create operations which does not require the user of this interface.
*
* @param <P> the type of the user value of the result of the previous step
* @see Operation#createWithBuilder(java.util.function.Consumer)
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface OperationBuilder<P> {
/**
* Interface used to provide the business object to modify to a model modification step based on the tag specified when creating th step
* and the result of the previous operation step.
* @param <T> the type of the tag.
* @param <B> the type of business object to modify
* @param <P> the type of the user value of the result of the previous step
* @since 2.0
* @see #modifyModel
*/
interface BusinessObjectToModifyProvider<T, B, P> {
/**
* Returns the business object that should be modified
* @param tag the tag specified when creating the model modification step
* @param previousUserValue the user
* @return the object to modify
*/
B getBusinessObject(T tag, P previousUserValue);
}
/**
* Create a model modification step.
* The business object passed to the modifier may be different from the object returned by the
* the business object provider. During operation execution, the appropriate modifiable object will be retrieved
* and passed to the modifier.
* @param <T> the type of the tag
* @param <B> the type of business object to modify
* @param <R> the type of the user value of the new step's result
* @param tag an object that will be passed to the model provider. May be null.
* @param boProvider the object which determines what business object is modified. Must not be null.
* @param modifier the object which performs the model modification. Must not be null.
* @return a new instance which adds steps after the newly created step.
* @since 2.0
*/
<T, B extends EObject, R> OperationBuilder<R> modifyModel(
T tag,
BusinessObjectToModifyProvider<T, B, P> boProvider,
ModelModifier<T, B, P, R> modifier);
/**
* Modifies the user value contained in the previous step's result. The previous result must be an {@link EObject} belonging to the AADL model.
* @param <R> the type of the user value of the new step's result
* @param modifier the object which performs the model modification. Must not return null
* @return a new instance which adds steps after the newly created step.
* @throws IllegalStateException if the user value from the previous step is not an instance of of {@link EObject}
*/
@SuppressWarnings("unchecked")
default <R> OperationBuilder<R> modifyPreviousResult(
final Function<P, StepResult<R>> modifier) {
return modifyModel(null, (tag, prevResult) -> {
if (!(prevResult instanceof EObject)) {
throw new IllegalStateException("Previous result must be an EObject. Previous result: " + prevResult);
}
return (EObject) prevResult;
}, (tag, boToModify, prevResult) -> modifier.apply((P) boToModify));
}
/**
* Creates a step which maps the user value provided by the previous step to a new value. The new value will be passed to
* subsequent steps.
* @param <R> the type of the user value of the new step's result
* @param mapper a function which returns the result for the step. The user value from this result will be used for subsequent steps in this branch.
* @return a new instance which adds steps after the newly created step.
*/
<R> OperationBuilder<R> map(
Function<P, StepResult<R>> mapper);
/**
* Create a step which executes another operation. This function is intended for use only in the rare cases that the number of steps is not known
* until runtime.
* @param opProvider a function that provides a operation to execute.
* @since 2.0
*/
void executeOperation(Function<P, Operation> opProvider);
/**
* Creates a new step which uses the value provided by the specified supplier as the user value of the result.
* This is equivalent to a a map step which ignores the previous result.
* @param <R> the type of the user value of the new step's result
* @param supplier the supplier which returns the user value for the step's result
* @return a new instance which adds steps after the newly created step.
* @see #map(Function)
*/
default <R> OperationBuilder<R> supply(final Supplier<StepResult<R>> supplier) {
return map(prevResult -> supplier.get());
}
}