use of org.talend.sdk.component.api.component.Version in project component-runtime by Talend.
the class MigrationHandlerFactory method findMigrationHandler.
public MigrationHandler findMigrationHandler(final List<ParameterMeta> parameterMetas, final Class<?> type, final ComponentManager.AllServices services) {
final MigrationHandler implicitMigrationHandler = ofNullable(parameterMetas).map(Collection::stream).orElseGet(Stream::empty).filter(p -> p.getMetadata().keySet().stream().anyMatch(k -> k.startsWith("tcomp::configurationtype::"))).filter(p -> Class.class.isInstance(p.getJavaType())).map(p -> {
// for now we can assume it is not in arrays
final MigrationHandler handler = findMigrationHandler(emptyList(), Class.class.cast(p.getJavaType()), services);
if (handler == NO_MIGRATION) {
return null;
}
final String prefix = p.getPath();
return (Function<Map<String, String>, Map<String, String>>) map -> {
final String version = map.get(String.format("%s.__version", prefix));
final Map<String, String> result;
if (version != null) {
final Map<String, String> migrated = ofNullable(handler.migrate(Integer.parseInt(version.trim()), map.entrySet().stream().filter(e -> e.getKey().startsWith(prefix + '.')).collect(toMap(e -> e.getKey().substring(prefix.length() + 1), Map.Entry::getValue)))).orElseGet(Collections::emptyMap);
result = migrated.entrySet().stream().collect(toMap(e -> prefix + '.' + e.getKey(), Map.Entry::getValue));
} else {
log.debug("No version for {} so skipping any potential migration", p.getJavaType().toString());
result = map;
}
return result;
};
}).filter(Objects::nonNull).reduce(NO_MIGRATION, (current, partial) -> (incomingVersion, incomingData) -> current.migrate(incomingVersion, partial.apply(incomingData)), (migrationHandler, migrationHandler2) -> (incomingVersion, incomingData) -> migrationHandler2.migrate(incomingVersion, migrationHandler.migrate(incomingVersion, incomingData)));
return ofNullable(type.getAnnotation(Version.class)).map(Version::migrationHandler).filter(t -> t != MigrationHandler.class).flatMap(t -> Stream.of(t.getConstructors()).sorted((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()).findFirst()).map(t -> services.getServices().computeIfAbsent(t.getDeclaringClass(), k -> {
try {
return t.newInstance(reflections.parameterFactory(t, services.getServices()).apply(emptyMap()));
} catch (final InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException(e);
} catch (final InvocationTargetException e) {
throw toRuntimeException(e);
}
})).map(MigrationHandler.class::cast).map(h -> {
if (implicitMigrationHandler == NO_MIGRATION) {
return h;
}
return (MigrationHandler) (incomingVersion, incomingData) -> h.migrate(incomingVersion, implicitMigrationHandler.migrate(incomingVersion, incomingData));
}).orElse(implicitMigrationHandler);
}
use of org.talend.sdk.component.api.component.Version in project component-runtime by Talend.
the class RepositoryModelBuilder method createConfig.
private Config createConfig(final ComponentManager.AllServices services, final ParameterMeta config, final String familyName, final String familyIcon, final MigrationHandlerFactory migrationHandlerFactory) {
final Config c = new Config();
c.setIcon(familyIcon);
c.setKey(getKey(familyName, config.getMetadata()));
c.setMeta(config);
c.setId(IdGenerator.get(c.getKey().getFamily(), c.getKey().getConfigType(), c.getKey().getConfigName()));
if (Class.class.isInstance(config.getJavaType())) {
final Class<?> clazz = Class.class.cast(config.getJavaType());
final Version version = clazz.getAnnotation(Version.class);
if (version != null) {
c.setVersion(version.value());
if (version.migrationHandler() != MigrationHandler.class) {
c.setMigrationHandler(migrationHandlerFactory.findMigrationHandler(config.getNestedParameters(), clazz, services));
}
} else {
c.setVersion(-1);
}
}
if (c.getMigrationHandler() == null) {
c.setMigrationHandler((v, d) -> d);
}
return c;
}
Aggregations