FDBoundaryFactory.java
package net.finmath.finitedifference.assetderivativevaluation.boundaries;
import java.lang.reflect.Constructor;
import net.finmath.finitedifference.FiniteDifferenceModel;
import net.finmath.finitedifference.assetderivativevaluation.products.FiniteDifferenceEquityProduct;
/**
* Factory for creating {@link FiniteDifferenceBoundary} instances.
*
* <p>
* The factory creates a boundary class based on naming conventions.
* Given a product and a model, it constructs the boundary class name
* as
* </p>
*
* <pre>
* <ProductSimpleName><ModelCoreName>Boundary
* </pre>
*
* <p>
* where {@code ModelCoreName} is obtained by removing the prefix
* {@code "FDM"} from the model class name.
* </p>
*
* <p>
* The boundary class must:
* </p>
* <ul>
* <li>Be located in the same package as this factory</li>
* <li>Provide a constructor accepting the concrete model type</li>
* </ul>
*
* @author Andrea Mazzon
*/
public final class FDBoundaryFactory {
/**
* Creates a {@link FiniteDifferenceBoundary} corresponding to the
* given model and product.
*
* @param model The finite difference model.
* @param product The finite difference product.
* @return The corresponding boundary implementation.
* @throws IllegalArgumentException If the boundary class cannot be created.
*/
public static FiniteDifferenceBoundary createBoundary(
final FiniteDifferenceModel model,
final FiniteDifferenceEquityProduct product) {
final String modelSimpleName = model.getClass().getSimpleName();
final String modelCoreName = modelSimpleName.replaceFirst("^FDM", "");
final String packageName = FDBoundaryFactory.class.getPackage().getName();
Class<?> productClass = product.getClass();
while (productClass != null
&& FiniteDifferenceEquityProduct.class.isAssignableFrom(productClass)) {
final String boundaryClassName =
packageName + "."
+ productClass.getSimpleName()
+ modelCoreName
+ "Boundary";
try {
final Class<?> boundaryClass = Class.forName(boundaryClassName);
final Constructor<?> constructor = boundaryClass.getConstructor(model.getClass());
return (FiniteDifferenceBoundary) constructor.newInstance(model);
}
catch (final ClassNotFoundException ignored) {
productClass = productClass.getSuperclass();
}
catch (final ReflectiveOperationException e) {
throw new IllegalArgumentException(
"Cannot instantiate boundary " + boundaryClassName
+ " for model type " + model.getClass()
+ " and product type " + product.getClass(),
e
);
}
}
throw new IllegalArgumentException(
"Cannot create boundary for model type "
+ model.getClass()
+ " and product type "
+ product.getClass()
);
}
}