release version 1.11.0
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.CopyTo;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class CollectionActions implements AtlasFieldAction {
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY)
|
||||
public static Object[] copyTo(CopyTo action, Object input) {
|
||||
// This a noop processor. Nevertheless it's signature is important to signal that's a one-to-many action.
|
||||
// It's behavior is implemented directly into DefaultAtlasContext
|
||||
return new Object[]{};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.AddDays;
|
||||
import io.atlasmap.v2.AddSeconds;
|
||||
import io.atlasmap.v2.CurrentDate;
|
||||
import io.atlasmap.v2.CurrentDateTime;
|
||||
import io.atlasmap.v2.CurrentTime;
|
||||
import io.atlasmap.v2.DayOfMonth;
|
||||
import io.atlasmap.v2.DayOfWeek;
|
||||
import io.atlasmap.v2.DayOfYear;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class DateFieldActions implements AtlasFieldAction {
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY_DATE)
|
||||
public static ZonedDateTime addDays(AddDays addDays, ZonedDateTime input) {
|
||||
if (addDays == null) {
|
||||
throw new IllegalArgumentException("AddDays action must be specified");
|
||||
}
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return input.plusDays(addDays.getDays() == null ? 0L : addDays.getDays());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY_DATE)
|
||||
public static ZonedDateTime addSeconds(AddSeconds addSeconds, ZonedDateTime input) {
|
||||
if (addSeconds == null) {
|
||||
throw new IllegalArgumentException("AddSeconds action must be specified");
|
||||
}
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return input.plusSeconds(addSeconds.getSeconds() == null ? 0L : addSeconds.getSeconds());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static ZonedDateTime currentDate(CurrentDate action) {
|
||||
return LocalDate.now().atStartOfDay(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static ZonedDateTime currentDateTime(CurrentDateTime action) {
|
||||
return LocalDate.now().atStartOfDay(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static ZonedDateTime currentTime(CurrentTime action) {
|
||||
return LocalTime.now().atDate(LocalDate.now()).atZone(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY_DATE)
|
||||
public static Integer dayOfMonth(DayOfMonth action, ZonedDateTime input) {
|
||||
return input == null ? null : input.getDayOfMonth();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY_DATE)
|
||||
public static Integer dayOfWeek(DayOfWeek action, ZonedDateTime input) {
|
||||
return input == null ? null : input.getDayOfWeek().getValue();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY_DATE)
|
||||
public static Integer dayOfYear(DayOfYear action, ZonedDateTime input) {
|
||||
return input == null ? null : input.getDayOfYear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-libs
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package io.atlasmap.actions;
|
||||
|
||||
import org.osgi.framework.ServiceException;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
import io.atlasmap.entaxy.OsgiHelper;
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.entaxy.MapData;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.modules.datamapper.DataMapperService;
|
||||
|
||||
public class EntaxyActions implements AtlasFieldAction {
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Object mapData(MapData mapData, Object input) {
|
||||
if (mapData == null) {
|
||||
throw new IllegalArgumentException("MapData action must be specified");
|
||||
}
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object result = null;
|
||||
|
||||
if (!CommonUtils.isValid(mapData.getMapToUse()))
|
||||
throw new IllegalArgumentException("MapToUse must be specified");
|
||||
ServiceReference<DataMapperService> ref = null;
|
||||
try {
|
||||
ref = OsgiHelper.getServiceRef(DataMapperService.class);
|
||||
if (ref == null)
|
||||
throw new ServiceException("DataMapperService service not available");
|
||||
DataMapperService dataMapperService = OsgiHelper.getService(ref);
|
||||
result = dataMapperService.getValue(mapData.getMapToUse(), input, !mapData.isDisableTrimWhitespace());
|
||||
if (result == null)
|
||||
throw new IllegalArgumentException();
|
||||
} catch (Exception e) {
|
||||
switch (mapData.getNoDataAction()) {
|
||||
case RETURN_NULL:
|
||||
result = null;
|
||||
break;
|
||||
case THROW_EXCEPTION:
|
||||
throw e;
|
||||
case USE_ORIGIN:
|
||||
result = input;
|
||||
break;
|
||||
case RETURN_VALUE:
|
||||
result = mapData.getNoDataValue();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
OsgiHelper.ungetService(ref);
|
||||
} catch (Exception ignore) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
if (result == null)
|
||||
return result;
|
||||
|
||||
switch (mapData.getReturnType()) {
|
||||
case STRING:
|
||||
result = result.toString();
|
||||
break;
|
||||
case BOOLEAN:
|
||||
try {
|
||||
result = Boolean.valueOf(result.toString());
|
||||
} catch (Exception ignore) {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case LONG:
|
||||
try {
|
||||
result = Long.parseLong(result.toString());
|
||||
} catch (Exception ignore) {
|
||||
result = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case DOUBLE:
|
||||
try {
|
||||
result = Double.parseDouble(result.toString());
|
||||
} catch (Exception ignore) {
|
||||
result = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import static io.atlasmap.v2.AtlasModelFactory.unwrapField;
|
||||
import static io.atlasmap.v2.AtlasModelFactory.wrapWithField;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.core.DefaultAtlasFunctionResolver;
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
public class ExpressionFieldAction implements AtlasFieldAction {
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Object process(io.atlasmap.v2.Expression action, List<Object> args) throws ExpressionException {
|
||||
if (action.getExpression() == null || action.getExpression().trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Expression parsedExpression = Expression.parse(action.getExpression(), DefaultAtlasFunctionResolver.getInstance());
|
||||
Field answer = parsedExpression.evaluate((index) -> {
|
||||
try {
|
||||
return wrapWithField(args.get(Integer.parseInt(index)));
|
||||
} catch (Throwable e) {
|
||||
throw new ExpressionException("Invalid variable: " + index);
|
||||
}
|
||||
});
|
||||
return unwrapField(answer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.AbsoluteValue;
|
||||
import io.atlasmap.v2.Add;
|
||||
import io.atlasmap.v2.AreaUnitType;
|
||||
import io.atlasmap.v2.Average;
|
||||
import io.atlasmap.v2.Ceiling;
|
||||
import io.atlasmap.v2.ConvertAreaUnit;
|
||||
import io.atlasmap.v2.ConvertDistanceUnit;
|
||||
import io.atlasmap.v2.ConvertMassUnit;
|
||||
import io.atlasmap.v2.ConvertVolumeUnit;
|
||||
import io.atlasmap.v2.DistanceUnitType;
|
||||
import io.atlasmap.v2.Divide;
|
||||
import io.atlasmap.v2.Floor;
|
||||
import io.atlasmap.v2.MassUnitType;
|
||||
import io.atlasmap.v2.Maximum;
|
||||
import io.atlasmap.v2.Minimum;
|
||||
import io.atlasmap.v2.Multiply;
|
||||
import io.atlasmap.v2.Round;
|
||||
import io.atlasmap.v2.Subtract;
|
||||
import io.atlasmap.v2.VolumeUnitType;
|
||||
|
||||
public class NumberFieldActions implements AtlasFieldAction {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(NumberFieldActions.class);
|
||||
|
||||
// 1D
|
||||
private static final double KILO_GRAMS_IN_A_POUND = 0.45359237;
|
||||
private static final double YARDS_IN_A_MILE = 1760.0;
|
||||
private static final double FEET_IN_A_YARD = 3.0;
|
||||
private static final double INCHES_IN_A_FOOT = 12.0;
|
||||
private static final double METERS_IN_A_INCH = 0.0254;
|
||||
// 2D
|
||||
private static final double SQUARE_FEET_IN_A_SQUARE_METER = Math.pow(1.0 / METERS_IN_A_INCH / INCHES_IN_A_FOOT,
|
||||
2.0);
|
||||
private static final double SQUARE_METERS_IN_A_SQUARE_MILE = Math
|
||||
.pow(YARDS_IN_A_MILE * FEET_IN_A_YARD * INCHES_IN_A_FOOT * METERS_IN_A_INCH, 2.0);
|
||||
private static final double SQUARE_FEET_IN_A_SQUARE_MILE = Math.pow(YARDS_IN_A_MILE * FEET_IN_A_YARD, 2.0);
|
||||
// 3D
|
||||
private static final double LITERS_IN_A_CUBIC_METER = 1000.0;
|
||||
private static final double CUBIC_FEET_IN_A_CUBIC_METER = Math.pow(1.0 / METERS_IN_A_INCH / INCHES_IN_A_FOOT, 3.0);
|
||||
private static final double GALLONS_US_FLUID_IN_A_CUBIC_METER = 264.17205236;
|
||||
|
||||
private static Map<MassUnitType, Map<MassUnitType, Double>> massConvertionTable;
|
||||
static {
|
||||
Map<MassUnitType, Map<MassUnitType, Double>> rootTable = new EnumMap<>(MassUnitType.class);
|
||||
Map<MassUnitType, Double> kgRates = new EnumMap<>(MassUnitType.class);
|
||||
kgRates.put(MassUnitType.KILOGRAM_KG, 1.0);
|
||||
kgRates.put(MassUnitType.POUND_LB, 1.0 / KILO_GRAMS_IN_A_POUND);
|
||||
rootTable.put(MassUnitType.KILOGRAM_KG, Collections.unmodifiableMap(kgRates));
|
||||
Map<MassUnitType, Double> lbsRates = new EnumMap<>(MassUnitType.class);
|
||||
lbsRates.put(MassUnitType.KILOGRAM_KG, KILO_GRAMS_IN_A_POUND);
|
||||
lbsRates.put(MassUnitType.POUND_LB, 1.0);
|
||||
rootTable.put(MassUnitType.POUND_LB, Collections.unmodifiableMap(lbsRates));
|
||||
massConvertionTable = Collections.unmodifiableMap(rootTable);
|
||||
}
|
||||
|
||||
private static Map<DistanceUnitType, Map<DistanceUnitType, Double>> distanceConvertionTable;
|
||||
static {
|
||||
Map<DistanceUnitType, Map<DistanceUnitType, Double>> rootTable = new EnumMap<>(DistanceUnitType.class);
|
||||
Map<DistanceUnitType, Double> mRates = new EnumMap<>(DistanceUnitType.class);
|
||||
mRates.put(DistanceUnitType.METER_M, 1.0);
|
||||
mRates.put(DistanceUnitType.FOOT_FT, 1.0 / METERS_IN_A_INCH / INCHES_IN_A_FOOT);
|
||||
mRates.put(DistanceUnitType.YARD_YD, 1.0 / METERS_IN_A_INCH / INCHES_IN_A_FOOT / FEET_IN_A_YARD);
|
||||
mRates.put(DistanceUnitType.MILE_MI, 1.0 / METERS_IN_A_INCH / INCHES_IN_A_FOOT / FEET_IN_A_YARD / YARDS_IN_A_MILE);
|
||||
mRates.put(DistanceUnitType.INCH_IN, 1.0 / METERS_IN_A_INCH);
|
||||
rootTable.put(DistanceUnitType.METER_M, Collections.unmodifiableMap(mRates));
|
||||
Map<DistanceUnitType, Double> ftRates = new EnumMap<>(DistanceUnitType.class);
|
||||
ftRates.put(DistanceUnitType.METER_M, INCHES_IN_A_FOOT * METERS_IN_A_INCH);
|
||||
ftRates.put(DistanceUnitType.FOOT_FT, 1.0);
|
||||
ftRates.put(DistanceUnitType.YARD_YD, 1.0 / FEET_IN_A_YARD);
|
||||
ftRates.put(DistanceUnitType.MILE_MI, 1.0 / FEET_IN_A_YARD / YARDS_IN_A_MILE);
|
||||
ftRates.put(DistanceUnitType.INCH_IN, INCHES_IN_A_FOOT);
|
||||
rootTable.put(DistanceUnitType.FOOT_FT, Collections.unmodifiableMap(ftRates));
|
||||
Map<DistanceUnitType, Double> ydRates = new EnumMap<>(DistanceUnitType.class);
|
||||
ydRates.put(DistanceUnitType.METER_M, FEET_IN_A_YARD * INCHES_IN_A_FOOT * METERS_IN_A_INCH);
|
||||
ydRates.put(DistanceUnitType.FOOT_FT, FEET_IN_A_YARD);
|
||||
ydRates.put(DistanceUnitType.YARD_YD, 1.0);
|
||||
ydRates.put(DistanceUnitType.MILE_MI, 1.0 / YARDS_IN_A_MILE);
|
||||
ydRates.put(DistanceUnitType.INCH_IN, FEET_IN_A_YARD * INCHES_IN_A_FOOT);
|
||||
rootTable.put(DistanceUnitType.YARD_YD, Collections.unmodifiableMap(ydRates));
|
||||
Map<DistanceUnitType, Double> miRates = new EnumMap<>(DistanceUnitType.class);
|
||||
miRates.put(DistanceUnitType.METER_M, YARDS_IN_A_MILE * FEET_IN_A_YARD * INCHES_IN_A_FOOT * METERS_IN_A_INCH);
|
||||
miRates.put(DistanceUnitType.FOOT_FT, YARDS_IN_A_MILE * FEET_IN_A_YARD);
|
||||
miRates.put(DistanceUnitType.YARD_YD, YARDS_IN_A_MILE);
|
||||
miRates.put(DistanceUnitType.MILE_MI, 1.0);
|
||||
miRates.put(DistanceUnitType.INCH_IN, YARDS_IN_A_MILE * FEET_IN_A_YARD * INCHES_IN_A_FOOT);
|
||||
rootTable.put(DistanceUnitType.MILE_MI, Collections.unmodifiableMap(miRates));
|
||||
Map<DistanceUnitType, Double> inRates = new EnumMap<>(DistanceUnitType.class);
|
||||
inRates.put(DistanceUnitType.METER_M, METERS_IN_A_INCH);
|
||||
inRates.put(DistanceUnitType.FOOT_FT, 1.0 / INCHES_IN_A_FOOT);
|
||||
inRates.put(DistanceUnitType.YARD_YD, 1.0 / INCHES_IN_A_FOOT / FEET_IN_A_YARD);
|
||||
inRates.put(DistanceUnitType.MILE_MI, 1.0 / INCHES_IN_A_FOOT / FEET_IN_A_YARD / YARDS_IN_A_MILE);
|
||||
inRates.put(DistanceUnitType.INCH_IN, 1.0);
|
||||
rootTable.put(DistanceUnitType.INCH_IN, Collections.unmodifiableMap(inRates));
|
||||
distanceConvertionTable = Collections.unmodifiableMap(rootTable);
|
||||
}
|
||||
|
||||
private static Map<AreaUnitType, Map<AreaUnitType, Double>> areaConvertionTable;
|
||||
static {
|
||||
Map<AreaUnitType, Map<AreaUnitType, Double>> rootTable = new EnumMap<>(AreaUnitType.class);
|
||||
Map<AreaUnitType, Double> m2Rates = new EnumMap<>(AreaUnitType.class);
|
||||
m2Rates.put(AreaUnitType.SQUARE_METER, 1.0);
|
||||
m2Rates.put(AreaUnitType.SQUARE_FOOT, SQUARE_FEET_IN_A_SQUARE_METER);
|
||||
m2Rates.put(AreaUnitType.SQUARE_MILE, 1.0 / SQUARE_METERS_IN_A_SQUARE_MILE);
|
||||
rootTable.put(AreaUnitType.SQUARE_METER, Collections.unmodifiableMap(m2Rates));
|
||||
Map<AreaUnitType, Double> ft2Rates = new EnumMap<>(AreaUnitType.class);
|
||||
ft2Rates.put(AreaUnitType.SQUARE_METER, 1.0 / SQUARE_FEET_IN_A_SQUARE_METER);
|
||||
ft2Rates.put(AreaUnitType.SQUARE_FOOT, 1.0);
|
||||
ft2Rates.put(AreaUnitType.SQUARE_MILE, 1.0 / SQUARE_FEET_IN_A_SQUARE_MILE);
|
||||
rootTable.put(AreaUnitType.SQUARE_FOOT, Collections.unmodifiableMap(ft2Rates));
|
||||
Map<AreaUnitType, Double> mi2Rates = new EnumMap<>(AreaUnitType.class);
|
||||
mi2Rates.put(AreaUnitType.SQUARE_METER, SQUARE_METERS_IN_A_SQUARE_MILE);
|
||||
mi2Rates.put(AreaUnitType.SQUARE_FOOT, SQUARE_FEET_IN_A_SQUARE_MILE);
|
||||
mi2Rates.put(AreaUnitType.SQUARE_MILE, 1.0);
|
||||
rootTable.put(AreaUnitType.SQUARE_MILE, Collections.unmodifiableMap(mi2Rates));
|
||||
areaConvertionTable = Collections.unmodifiableMap(rootTable);
|
||||
}
|
||||
|
||||
private static Map<VolumeUnitType, Map<VolumeUnitType, Double>> volumeConvertionTable;
|
||||
static {
|
||||
Map<VolumeUnitType, Map<VolumeUnitType, Double>> rootTable = new EnumMap<>(VolumeUnitType.class);
|
||||
Map<VolumeUnitType, Double> m3Rates = new EnumMap<>(VolumeUnitType.class);
|
||||
m3Rates.put(VolumeUnitType.CUBIC_METER, 1.0);
|
||||
m3Rates.put(VolumeUnitType.LITER, LITERS_IN_A_CUBIC_METER);
|
||||
m3Rates.put(VolumeUnitType.CUBIC_FOOT, CUBIC_FEET_IN_A_CUBIC_METER);
|
||||
m3Rates.put(VolumeUnitType.GALLON_US_FLUID, GALLONS_US_FLUID_IN_A_CUBIC_METER);
|
||||
rootTable.put(VolumeUnitType.CUBIC_METER, Collections.unmodifiableMap(m3Rates));
|
||||
Map<VolumeUnitType, Double> literRates = new EnumMap<>(VolumeUnitType.class);
|
||||
literRates.put(VolumeUnitType.CUBIC_METER, 1.0 / LITERS_IN_A_CUBIC_METER);
|
||||
literRates.put(VolumeUnitType.LITER, 1.0);
|
||||
literRates.put(VolumeUnitType.CUBIC_FOOT, 1.0 / LITERS_IN_A_CUBIC_METER * CUBIC_FEET_IN_A_CUBIC_METER);
|
||||
literRates.put(VolumeUnitType.GALLON_US_FLUID,
|
||||
1.0 / LITERS_IN_A_CUBIC_METER * GALLONS_US_FLUID_IN_A_CUBIC_METER);
|
||||
rootTable.put(VolumeUnitType.LITER, Collections.unmodifiableMap(literRates));
|
||||
Map<VolumeUnitType, Double> cftRates = new EnumMap<>(VolumeUnitType.class);
|
||||
cftRates.put(VolumeUnitType.CUBIC_METER, 1.0 / CUBIC_FEET_IN_A_CUBIC_METER);
|
||||
cftRates.put(VolumeUnitType.LITER, 1.0 / CUBIC_FEET_IN_A_CUBIC_METER * LITERS_IN_A_CUBIC_METER);
|
||||
cftRates.put(VolumeUnitType.CUBIC_FOOT, 1.0);
|
||||
cftRates.put(VolumeUnitType.GALLON_US_FLUID,
|
||||
1.0 / CUBIC_FEET_IN_A_CUBIC_METER * GALLONS_US_FLUID_IN_A_CUBIC_METER);
|
||||
rootTable.put(VolumeUnitType.CUBIC_FOOT, Collections.unmodifiableMap(cftRates));
|
||||
Map<VolumeUnitType, Double> galUsFluidRates = new EnumMap<>(VolumeUnitType.class);
|
||||
galUsFluidRates.put(VolumeUnitType.CUBIC_METER, 1.0 / GALLONS_US_FLUID_IN_A_CUBIC_METER);
|
||||
galUsFluidRates.put(VolumeUnitType.LITER, 1.0 / GALLONS_US_FLUID_IN_A_CUBIC_METER * LITERS_IN_A_CUBIC_METER);
|
||||
galUsFluidRates.put(VolumeUnitType.CUBIC_FOOT,
|
||||
1.0 / GALLONS_US_FLUID_IN_A_CUBIC_METER * CUBIC_FEET_IN_A_CUBIC_METER);
|
||||
galUsFluidRates.put(VolumeUnitType.GALLON_US_FLUID, 1.0);
|
||||
rootTable.put(VolumeUnitType.GALLON_US_FLUID, Collections.unmodifiableMap(galUsFluidRates));
|
||||
volumeConvertionTable = Collections.unmodifiableMap(rootTable);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number absoluteValue(AbsoluteValue action, Number input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
if (input instanceof BigDecimal) {
|
||||
return ((BigDecimal) input).abs();
|
||||
}
|
||||
if (requiresDoubleResult(input)) {
|
||||
return Math.abs(input.doubleValue());
|
||||
}
|
||||
return Math.abs(input.longValue());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number add(Add action, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Number sum = 0L;
|
||||
for (Object entry : inputs) {
|
||||
if (entry instanceof Number) {
|
||||
if (sum instanceof BigDecimal) {
|
||||
sum = ((BigDecimal) sum).add(BigDecimal.valueOf(((Number) entry).doubleValue()));
|
||||
} else if (entry instanceof BigDecimal) {
|
||||
sum = BigDecimal.valueOf(sum.doubleValue()).add((BigDecimal) entry);
|
||||
} else if (requiresDoubleResult(sum) || requiresDoubleResult(entry)) {
|
||||
sum = sum.doubleValue() + ((Number) entry).doubleValue();
|
||||
} else {
|
||||
sum = sum.longValue() + ((Number) entry).longValue();
|
||||
}
|
||||
} else {
|
||||
warnIgnoringValue("Add", entry);
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number average(Average action, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
return add(null, inputs).doubleValue() / inputs.size();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number ceiling(Ceiling action, Number input) {
|
||||
return input == null ? 0L : (long)Math.ceil(input.doubleValue());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number convertMassUnit(ConvertMassUnit convertMassUnit, Number input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (convertMassUnit == null || convertMassUnit.getFromUnit() == null
|
||||
|| convertMassUnit.getToUnit() == null) {
|
||||
throw new IllegalArgumentException("ConvertMassUnit must be specified with fromUnit and toUnit");
|
||||
}
|
||||
|
||||
MassUnitType fromUnit = convertMassUnit.getFromUnit();
|
||||
MassUnitType toUnit = convertMassUnit.getToUnit();
|
||||
double rate = massConvertionTable.get(fromUnit).get(toUnit);
|
||||
return doMultiply(input, rate);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number convertDistanceUnit(ConvertDistanceUnit convertDistanceUnit, Number input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (convertDistanceUnit == null || convertDistanceUnit.getFromUnit() == null
|
||||
|| convertDistanceUnit.getToUnit() == null) {
|
||||
throw new IllegalArgumentException("ConvertDistanceUnit must be specified with fromUnit and toUnit");
|
||||
}
|
||||
|
||||
DistanceUnitType fromUnit = convertDistanceUnit.getFromUnit();
|
||||
DistanceUnitType toUnit = convertDistanceUnit.getToUnit();
|
||||
double rate = distanceConvertionTable.get(fromUnit).get(toUnit);
|
||||
return doMultiply(input, rate);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number convertAreaUnit(ConvertAreaUnit convertAreaUnit, Number input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (convertAreaUnit == null || convertAreaUnit.getFromUnit() == null
|
||||
|| convertAreaUnit.getToUnit() == null) {
|
||||
throw new IllegalArgumentException("ConvertAreaUnit must be specified with fromUnit and toUnit");
|
||||
}
|
||||
|
||||
AreaUnitType fromUnit = convertAreaUnit.getFromUnit();
|
||||
AreaUnitType toUnit = convertAreaUnit.getToUnit();
|
||||
double rate = areaConvertionTable.get(fromUnit).get(toUnit);
|
||||
return doMultiply(input, rate);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number convertVolumeUnit(ConvertVolumeUnit convertVolumeUnit, Number input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (convertVolumeUnit == null || convertVolumeUnit.getFromUnit() == null
|
||||
|| convertVolumeUnit.getToUnit() == null) {
|
||||
throw new IllegalArgumentException("ConvertVolumeUnit must be specified with fromUnit and toUnit");
|
||||
}
|
||||
|
||||
VolumeUnitType fromUnit = convertVolumeUnit.getFromUnit();
|
||||
VolumeUnitType toUnit = convertVolumeUnit.getToUnit();
|
||||
double rate = volumeConvertionTable.get(fromUnit).get(toUnit);
|
||||
return doMultiply(input, rate);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number divide(Divide divide, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Number quotient = null;
|
||||
for (Object entry : inputs) {
|
||||
if (entry instanceof Number) {
|
||||
if (quotient == null) {
|
||||
quotient = (Number) entry;
|
||||
} else if (quotient instanceof BigDecimal) {
|
||||
quotient = ((BigDecimal) quotient).divide(BigDecimal.valueOf(((Number) entry).doubleValue()));
|
||||
} else if (entry instanceof BigDecimal) {
|
||||
quotient = BigDecimal.valueOf(quotient.doubleValue()).divide((BigDecimal) entry);
|
||||
} else {
|
||||
quotient = quotient.doubleValue() / ((Number) entry).doubleValue();
|
||||
}
|
||||
} else {
|
||||
warnIgnoringValue("Divide", entry);
|
||||
}
|
||||
}
|
||||
|
||||
return quotient;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number floor(Floor floor, Number input) {
|
||||
return input == null ? 0L : (long)Math.floor(input.doubleValue());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number maximum(Maximum maximum, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Number max = null;
|
||||
for (Object entry : inputs) {
|
||||
if (entry instanceof Number) {
|
||||
if (max instanceof BigDecimal && entry instanceof BigDecimal) {
|
||||
max = ((BigDecimal) entry).max((BigDecimal)max);
|
||||
} else if (max == null || ((Number) entry).doubleValue() > max.doubleValue()) {
|
||||
max = (Number) entry;
|
||||
}
|
||||
} else {
|
||||
warnIgnoringValue("Maximum", entry);
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number minimum(Minimum minimum, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Number min = null;
|
||||
for (Object entry : inputs) {
|
||||
if (entry instanceof Number) {
|
||||
if (min instanceof BigDecimal && entry instanceof BigDecimal) {
|
||||
min = ((BigDecimal) entry).min((BigDecimal)min);
|
||||
} else if (min == null || ((Number) entry).doubleValue() < min.doubleValue()) {
|
||||
min = (Number) entry;
|
||||
}
|
||||
} else {
|
||||
warnIgnoringValue("Minimum", entry);
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number multiply(Multiply multiply, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Number product = 1L;
|
||||
for (Object entry : inputs) {
|
||||
if (entry instanceof Number) {
|
||||
if (product instanceof BigDecimal) {
|
||||
product = ((BigDecimal) product).multiply(BigDecimal.valueOf(((Number) entry).doubleValue()));
|
||||
} else if (entry instanceof BigDecimal) {
|
||||
product = BigDecimal.valueOf(product.doubleValue()).multiply((BigDecimal) entry);
|
||||
} else if (requiresDoubleResult(product) || requiresDoubleResult(entry)) {
|
||||
product = product.doubleValue() * ((Number) entry).doubleValue();
|
||||
} else {
|
||||
product = product.longValue() * ((Number) entry).longValue();
|
||||
}
|
||||
} else {
|
||||
warnIgnoringValue("Multiply", entry);
|
||||
}
|
||||
}
|
||||
|
||||
return product;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number round(Round action, Number input) {
|
||||
return input == null ? 0L : Math.round(input.doubleValue());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number subtract(Subtract subtract, List<Number> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Number difference = null;
|
||||
for (Object entry : inputs) {
|
||||
if (entry instanceof Number) {
|
||||
if (difference == null) {
|
||||
difference = (Number) entry;
|
||||
} else if (difference instanceof BigDecimal) {
|
||||
difference = ((BigDecimal) difference).subtract(BigDecimal.valueOf(((Number) entry).doubleValue()));
|
||||
} else if (entry instanceof BigDecimal) {
|
||||
difference = BigDecimal.valueOf(difference.doubleValue()).subtract((BigDecimal) entry);
|
||||
} else if (requiresDoubleResult(difference) || requiresDoubleResult(entry)) {
|
||||
difference = difference.doubleValue() - ((Number) entry).doubleValue();
|
||||
} else {
|
||||
difference = difference.longValue() - ((Number) entry).longValue();
|
||||
}
|
||||
} else {
|
||||
warnIgnoringValue("Subtract", entry);
|
||||
}
|
||||
}
|
||||
|
||||
return difference;
|
||||
}
|
||||
|
||||
private static Number doMultiply(Number input, double rate) {
|
||||
if (input instanceof BigDecimal) {
|
||||
return ((BigDecimal) input).multiply(BigDecimal.valueOf(rate));
|
||||
}
|
||||
return (input.doubleValue() * rate);
|
||||
}
|
||||
|
||||
private static boolean requiresDoubleResult(Object object) {
|
||||
return object instanceof Double || object instanceof Float;
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO Add audit via @AtlasSession instead - https://github.com/atlasmap/atlasmap/issues/1269
|
||||
* @param value value
|
||||
*/
|
||||
private static void warnIgnoringValue(String action, Object value) {
|
||||
LOG.warn("The source collection/arry/map must only contain numbers for '{}' transformation - ignoring '{}'",
|
||||
action, value != null ? value : "null");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.Contains;
|
||||
import io.atlasmap.v2.Count;
|
||||
import io.atlasmap.v2.Equals;
|
||||
import io.atlasmap.v2.IsNull;
|
||||
import io.atlasmap.v2.ItemAt;
|
||||
import io.atlasmap.v2.Length;
|
||||
|
||||
public class ObjectFieldActions implements AtlasFieldAction {
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Integer count(Count action, List<Object> inputs) {
|
||||
if (inputs == null) {
|
||||
return 0;
|
||||
}
|
||||
return inputs.size();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Boolean contains(Contains contains, List<Object> inputs) {
|
||||
if (contains == null) {
|
||||
throw new IllegalArgumentException("Contains action must be specified");
|
||||
}
|
||||
if (inputs == null) {
|
||||
return contains.getValue() == null;
|
||||
}
|
||||
return collectionContains(inputs, contains);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Boolean equals(Equals equals, Object input) {
|
||||
if (equals == null) {
|
||||
throw new IllegalArgumentException("Equals action must be specified");
|
||||
}
|
||||
if (input == null) {
|
||||
return equals.getValue() == null;
|
||||
}
|
||||
|
||||
return input.toString().equals(equals.getValue());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Boolean isNull(IsNull action, Object input) {
|
||||
return input == null;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Object itemAt(ItemAt itemAt, List<Object> inputs) {
|
||||
if (inputs == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer index = itemAt.getIndex() == null ? 0 : itemAt.getIndex();
|
||||
Object[] array = inputs.toArray(new Object[0]);
|
||||
if (array.length > index) {
|
||||
return array[index];
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException(String.format(
|
||||
"Collection '%s' has fewer (%s) than expected (%s)", array, array.length, index));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Integer length(Length length, Object input) {
|
||||
if (input == null) {
|
||||
return -1;
|
||||
}
|
||||
return input.toString().length();
|
||||
}
|
||||
|
||||
private static boolean collectionContains(Collection<?> collection, Contains contains) {
|
||||
for (Object item : collection) {
|
||||
if (item == null) {
|
||||
if (contains.getValue() == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (item.toString().equals(contains.getValue())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.Append;
|
||||
import io.atlasmap.v2.Concatenate;
|
||||
import io.atlasmap.v2.EndsWith;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
import io.atlasmap.v2.Format;
|
||||
import io.atlasmap.v2.GenerateUUID;
|
||||
import io.atlasmap.v2.IndexOf;
|
||||
import io.atlasmap.v2.LastIndexOf;
|
||||
import io.atlasmap.v2.PadStringLeft;
|
||||
import io.atlasmap.v2.PadStringRight;
|
||||
import io.atlasmap.v2.Prepend;
|
||||
import io.atlasmap.v2.Repeat;
|
||||
import io.atlasmap.v2.ReplaceAll;
|
||||
import io.atlasmap.v2.ReplaceFirst;
|
||||
import io.atlasmap.v2.Split;
|
||||
import io.atlasmap.v2.StartsWith;
|
||||
import io.atlasmap.v2.SubString;
|
||||
import io.atlasmap.v2.SubStringAfter;
|
||||
import io.atlasmap.v2.SubStringBefore;
|
||||
|
||||
public class StringComplexFieldActions implements AtlasFieldAction {
|
||||
|
||||
public static final String STRING_SEPARATOR_REGEX = "^\\s+:_+=";
|
||||
public static final Pattern STRING_SEPARATOR_PATTERN = Pattern.compile(STRING_SEPARATOR_REGEX);
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String append(Append append, String input) {
|
||||
if (append == null) {
|
||||
throw new IllegalArgumentException("Append must be specified with a string");
|
||||
}
|
||||
String string = append.getString();
|
||||
if (input == null && string == null) {
|
||||
return null;
|
||||
}
|
||||
if (string == null) {
|
||||
return input.toString();
|
||||
}
|
||||
return input == null ? string : input.toString().concat(string);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY)
|
||||
public static String concatenate(Concatenate concat, List<String> inputs) {
|
||||
if (concat == null) {
|
||||
throw new IllegalArgumentException("Concatenate must be specified with a delimiter");
|
||||
}
|
||||
if (inputs == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String delim = concat.getDelimiter() == null ? "" : concat.getDelimiter();
|
||||
boolean delimitingEmptyValues = concat.getDelimitingEmptyValues() == null
|
||||
? false
|
||||
: concat.getDelimitingEmptyValues();
|
||||
boolean isFirst = true;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String entry : inputs) {
|
||||
if (!isFirst && ((entry != null && !entry.isEmpty()) || delimitingEmptyValues)) {
|
||||
builder.append(delim);
|
||||
}
|
||||
if (entry != null) {
|
||||
builder.append(entry);
|
||||
}
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Boolean endsWith(EndsWith endsWith, String input) {
|
||||
if (endsWith == null || endsWith.getString() == null) {
|
||||
throw new IllegalArgumentException("EndsWith must be specified with a string");
|
||||
}
|
||||
|
||||
return input == null ? false : input.endsWith(endsWith.getString());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String format(Format format, List<Object> input) {
|
||||
if (format == null || format.getTemplate() == null) {
|
||||
throw new IllegalArgumentException("Format must be specified with a template");
|
||||
}
|
||||
|
||||
return String.format(Locale.ROOT, format.getTemplate(), input == null ? null : input.toArray(new Object[0]));
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String genareteUUID(GenerateUUID action) {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number indexOf(IndexOf indexOf, String input) {
|
||||
if (indexOf == null || indexOf.getString() == null) {
|
||||
throw new IllegalArgumentException("IndexOf must be specified with a string");
|
||||
}
|
||||
|
||||
return input == null ? -1 : input.indexOf(indexOf.getString());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Number lastIndexOf(LastIndexOf lastIndexOf, String input) {
|
||||
if (lastIndexOf == null || lastIndexOf.getString() == null) {
|
||||
throw new IllegalArgumentException("LastIndexOf must be specified with a string");
|
||||
}
|
||||
|
||||
return input == null ? -1 : input.lastIndexOf(lastIndexOf.getString());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String padStringRight(PadStringRight padStringRight, String input) {
|
||||
if (padStringRight == null || padStringRight.getPadCharacter() == null
|
||||
|| padStringRight.getPadCount() == null) {
|
||||
throw new IllegalArgumentException("PadStringRight must be specified with padCharacter and padCount");
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (input != null) {
|
||||
builder.append(input);
|
||||
}
|
||||
for (int i = 0; i < padStringRight.getPadCount(); i++) {
|
||||
builder.append(padStringRight.getPadCharacter());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String padStringLeft(PadStringLeft padStringLeft, String input) {
|
||||
if (padStringLeft == null || padStringLeft.getPadCharacter() == null
|
||||
|| padStringLeft.getPadCount() == null) {
|
||||
throw new IllegalArgumentException("PadStringLeft must be specified with padCharacter and padCount");
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < padStringLeft.getPadCount(); i++) {
|
||||
builder.append(padStringLeft.getPadCharacter());
|
||||
}
|
||||
if (input != null) {
|
||||
builder.append(input);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String prepend(Prepend action, String input) {
|
||||
String string = action.getString();
|
||||
if (input == null) {
|
||||
return string;
|
||||
}
|
||||
if (string == null) {
|
||||
return input;
|
||||
}
|
||||
return string.concat(input);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String replaceAll(ReplaceAll replaceAll, String input) {
|
||||
if (replaceAll == null || replaceAll.getMatch() == null || replaceAll.getMatch().isEmpty()) {
|
||||
throw new IllegalArgumentException("ReplaceAll action must be specified with a non-empty old string");
|
||||
}
|
||||
String match = replaceAll.getMatch();
|
||||
String newString = replaceAll.getNewString();
|
||||
return input == null ? null : input.replaceAll(match, newString == null ? "" : newString);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String replaceFirst(ReplaceFirst replaceFirst, String input) {
|
||||
if (replaceFirst == null || replaceFirst.getMatch() == null || replaceFirst.getMatch().isEmpty()) {
|
||||
throw new IllegalArgumentException("ReplaceFirst action must be specified with a non-empty old string");
|
||||
}
|
||||
String match = replaceFirst.getMatch();
|
||||
String newString = replaceFirst.getNewString();
|
||||
return input == null ? null : input.replaceFirst(match, newString == null ? "" : newString);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY)
|
||||
public static String[] split(Split split, String input) {
|
||||
if (split == null || split.getDelimiter() == null) {
|
||||
throw new IllegalArgumentException("Split must be specified with a delimiter");
|
||||
}
|
||||
String quotedDelimiter = Pattern.quote(split.getDelimiter());
|
||||
boolean collapseRepeatingDelimiter = split.getCollapseRepeatingDelimiters() == null
|
||||
? false
|
||||
: split.getCollapseRepeatingDelimiters();
|
||||
if (collapseRepeatingDelimiter) {
|
||||
quotedDelimiter = "(" + quotedDelimiter + ")+";
|
||||
}
|
||||
return input == null ? null : input.toString().split(quotedDelimiter);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor(sourceType = FieldType.ANY)
|
||||
public static String[] repeat(Repeat repeat, String input) {
|
||||
|
||||
if (repeat == null) {
|
||||
throw new IllegalArgumentException("repeat is not defined");
|
||||
}
|
||||
|
||||
String[] returnObj = null;
|
||||
|
||||
// Repeat the value based on count
|
||||
int count = repeat.getCount();
|
||||
|
||||
returnObj = new String[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
returnObj[i] = input;
|
||||
}
|
||||
|
||||
return returnObj;
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Boolean startsWith(StartsWith startsWith, String input) {
|
||||
if (startsWith == null || startsWith.getString() == null) {
|
||||
throw new IllegalArgumentException("StartsWith must be specified with a string");
|
||||
}
|
||||
|
||||
return input == null ? false : input.startsWith(startsWith.getString());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String subString(SubString subString, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
if (subString == null || subString.getStartIndex() == null || subString.getStartIndex() < 0) {
|
||||
throw new IllegalArgumentException("SubString action must be specified with a positive startIndex");
|
||||
}
|
||||
|
||||
return doSubString(input, subString.getStartIndex(), subString.getEndIndex());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String subStringAfter(SubStringAfter subStringAfter, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
if (subStringAfter == null || subStringAfter.getStartIndex() == null
|
||||
|| subStringAfter.getStartIndex() < 0 || subStringAfter.getMatch() == null
|
||||
|| (subStringAfter.getEndIndex() != null
|
||||
&& subStringAfter.getEndIndex() < subStringAfter.getStartIndex())) {
|
||||
throw new IllegalArgumentException(
|
||||
"SubStringAfter action must be specified with a positive startIndex and a string to match");
|
||||
}
|
||||
|
||||
int idx = input.indexOf(subStringAfter.getMatch());
|
||||
if (idx < 0) {
|
||||
return input;
|
||||
}
|
||||
idx = idx + subStringAfter.getMatch().length();
|
||||
return doSubString(input.substring(idx), subStringAfter.getStartIndex(), subStringAfter.getEndIndex());
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String subStringBefore(SubStringBefore subStringBefore, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
if (subStringBefore == null || subStringBefore.getStartIndex() == null
|
||||
|| subStringBefore.getStartIndex() < 0 || subStringBefore.getMatch() == null
|
||||
|| (subStringBefore.getEndIndex() != null
|
||||
&& subStringBefore.getEndIndex() < subStringBefore.getStartIndex())) {
|
||||
throw new IllegalArgumentException(
|
||||
"SubStringBefore action must be specified with a positive startIndex and a string to match");
|
||||
}
|
||||
|
||||
int idx = input.indexOf(subStringBefore.getMatch());
|
||||
if (idx < 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
return doSubString(input.substring(0, idx), subStringBefore.getStartIndex(), subStringBefore.getEndIndex());
|
||||
}
|
||||
|
||||
private static String doSubString(String input, Integer startIndex, Integer endIndex) {
|
||||
if (endIndex == null) {
|
||||
return input.substring(startIndex);
|
||||
}
|
||||
|
||||
return input.substring(startIndex, endIndex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.actions;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.atlasmap.spi.AtlasActionProcessor;
|
||||
import io.atlasmap.spi.AtlasFieldAction;
|
||||
import io.atlasmap.v2.Capitalize;
|
||||
import io.atlasmap.v2.FileExtension;
|
||||
import io.atlasmap.v2.Lowercase;
|
||||
import io.atlasmap.v2.LowercaseChar;
|
||||
import io.atlasmap.v2.Normalize;
|
||||
import io.atlasmap.v2.RemoveFileExtension;
|
||||
import io.atlasmap.v2.SeparateByDash;
|
||||
import io.atlasmap.v2.SeparateByUnderscore;
|
||||
import io.atlasmap.v2.Trim;
|
||||
import io.atlasmap.v2.TrimLeft;
|
||||
import io.atlasmap.v2.TrimRight;
|
||||
import io.atlasmap.v2.Uppercase;
|
||||
import io.atlasmap.v2.UppercaseChar;
|
||||
|
||||
public class StringSimpleFieldActions implements AtlasFieldAction {
|
||||
|
||||
public static final String STRING_SEPARATOR_REGEX = "[\\s+\\:\\_\\+\\=\\-]+";
|
||||
public static final Pattern STRING_SEPARATOR_PATTERN = Pattern.compile(STRING_SEPARATOR_REGEX);
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String capitalize(Capitalize action, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
if (input.length() == 1) {
|
||||
return String.valueOf(input.charAt(0)).toUpperCase();
|
||||
}
|
||||
return String.valueOf(input.charAt(0)).toUpperCase() + input.substring(1);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String fileExtension(FileExtension action, String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int ndx = input.lastIndexOf('.');
|
||||
return ndx < 0 ? null : input.substring(ndx + 1);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String lowercase(Lowercase action, String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return input.toLowerCase();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Character lowercaseChar(LowercaseChar action, Character input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return String.valueOf(input).toLowerCase().charAt(0);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String normalize(Normalize action, String input) {
|
||||
return input == null ? null : input.replaceAll("\\s+", " ").trim();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String removeFileExtension(RemoveFileExtension action, String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int ndx = input.lastIndexOf('.');
|
||||
return ndx < 0 ? input : input.substring(0, ndx);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String separateByDash(SeparateByDash action, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
return STRING_SEPARATOR_PATTERN.matcher(input).replaceAll("-");
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String separateByUnderscore(SeparateByUnderscore action, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
return STRING_SEPARATOR_PATTERN.matcher(input).replaceAll("_");
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String trim(Trim action, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
return input.trim();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String trimLeft(TrimLeft action, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (i < input.length() && Character.isWhitespace(input.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
return input.substring(i);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String trimRight(TrimRight action, String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
int i = input.length() - 1;
|
||||
while (i >= 0 && Character.isWhitespace(input.charAt(i))) {
|
||||
i--;
|
||||
}
|
||||
return input.substring(0, i + 1);
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static String uppercase(Uppercase action, String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return input.toUpperCase();
|
||||
}
|
||||
|
||||
@AtlasActionProcessor
|
||||
public static Character uppercaseChar(UppercaseChar action, Character input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return String.valueOf(input).toUpperCase().charAt(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
public class AtlasConstants {
|
||||
public static final String DEFAULT_SOURCE_DOCUMENT_ID = "ATLAS_DEFAULT_SOURCE_DOC";
|
||||
public static final String DEFAULT_TARGET_DOCUMENT_ID = "ATLAS_DEFAULT_TARGET_DOC";
|
||||
public static final String CONSTANTS_DOCUMENT_ID = "ATLAS_CONSTANTS_DOC";
|
||||
public static final String PROPERTIES_SOURCE_DOCUMENT_ID = "ATLAS_SOURCE_PROPERTIES_DOC";
|
||||
public static final String PROPERTIES_TARGET_DOCUMENT_ID = "ATLAS_TARGET_PROPERTIES_DOC";
|
||||
|
||||
private AtlasConstants() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
import io.atlasmap.v2.Audits;
|
||||
import io.atlasmap.v2.Mapping;
|
||||
|
||||
public interface AtlasContext {
|
||||
|
||||
AtlasContextFactory getContextFactory();
|
||||
|
||||
AtlasSession createSession() throws AtlasException;
|
||||
|
||||
/*
|
||||
* https://github.com/atlasmap/atlasmap/issues/872
|
||||
* Consider moving following 3 methods into AtlasSession in V2
|
||||
*/
|
||||
|
||||
void process(AtlasSession session) throws AtlasException;
|
||||
|
||||
void processValidation(AtlasSession session) throws AtlasException;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@code AtlasPreviewContext#processPreview(Mapping)}
|
||||
*
|
||||
* @param mapping A mapping item to process preview
|
||||
* @return A list of audit log
|
||||
*/
|
||||
@Deprecated
|
||||
Audits processPreview(Mapping mapping) throws AtlasException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import io.atlasmap.spi.AtlasCombineStrategy;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasFieldActionService;
|
||||
import io.atlasmap.spi.AtlasPropertyStrategy;
|
||||
import io.atlasmap.spi.AtlasSeparateStrategy;
|
||||
|
||||
public interface AtlasContextFactory {
|
||||
|
||||
static final String PROPERTY_ATLASMAP_CORE_VERSION = "atlasmap.core.version";
|
||||
|
||||
enum Format { ADM, JSON };
|
||||
|
||||
void init();
|
||||
|
||||
void destroy();
|
||||
|
||||
AtlasContext createContext(File atlasMappingFile) throws AtlasException;
|
||||
|
||||
AtlasContext createContext(URI atlasMappingUri) throws AtlasException;
|
||||
|
||||
AtlasContext createContext(Format format, InputStream atlasMappingStream) throws AtlasException;
|
||||
|
||||
AtlasPreviewContext createPreviewContext() throws AtlasException;
|
||||
|
||||
@Deprecated
|
||||
AtlasCombineStrategy getCombineStrategy() throws AtlasException;
|
||||
|
||||
AtlasConversionService getConversionService() throws AtlasException;
|
||||
|
||||
AtlasFieldActionService getFieldActionService() throws AtlasException;
|
||||
|
||||
AtlasPropertyStrategy getPropertyStrategy() throws AtlasException;
|
||||
|
||||
void setPropertyStrategy(AtlasPropertyStrategy strategy) throws AtlasException;
|
||||
|
||||
@Deprecated
|
||||
AtlasSeparateStrategy getSeparateStrategy() throws AtlasException;
|
||||
|
||||
AtlasValidationService getValidationService() throws AtlasException;
|
||||
|
||||
void setProperties(Map<String, String> properties);
|
||||
|
||||
void setProperties(Properties properties);
|
||||
|
||||
Map<String, String> getProperties();
|
||||
|
||||
void addClassLoader(ClassLoader cl);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
public class AtlasConversionException extends AtlasException {
|
||||
|
||||
private static final long serialVersionUID = -8909275615751481096L;
|
||||
|
||||
public AtlasConversionException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AtlasConversionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AtlasConversionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AtlasConversionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link io.atlasmap.spi.AtlasConverter}
|
||||
* @param <T> Java type to convert from
|
||||
*/
|
||||
@Deprecated
|
||||
public interface AtlasConverter<T> extends io.atlasmap.spi.AtlasConverter<T> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
public class AtlasException extends Exception {
|
||||
private static final long serialVersionUID = 7547364931796852076L;
|
||||
|
||||
public AtlasException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AtlasException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AtlasException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AtlasException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link io.atlasmap.spi.AtlasFieldAction}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface AtlasFieldAction extends io.atlasmap.spi.AtlasFieldAction {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
/**
|
||||
* An interface to define a custom mapping logic. User can implement this class and
|
||||
* define custom mapping logic in {@code #processMapping()}.
|
||||
*
|
||||
*/
|
||||
public interface AtlasMappingBuilder {
|
||||
|
||||
/**
|
||||
* Define custom mapping logic. User can implement this interface and define
|
||||
* custom mapping logic in this method.
|
||||
*/
|
||||
void process();
|
||||
|
||||
/**
|
||||
* Set {@code AtlasSession}.
|
||||
* @param session {@code AtlasSession}
|
||||
* @throws AtlasException
|
||||
*/
|
||||
void setAtlasSession(AtlasSession session) throws AtlasException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
public class AtlasNotFoundException extends AtlasException {
|
||||
|
||||
private static final long serialVersionUID = -780179923312820477L;
|
||||
|
||||
public AtlasNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AtlasNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AtlasNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AtlasNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
import io.atlasmap.v2.Audits;
|
||||
import io.atlasmap.v2.Mapping;
|
||||
|
||||
public interface AtlasPreviewContext {
|
||||
|
||||
Audits processPreview(Mapping mapping) throws AtlasException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.atlasmap.spi.AtlasPropertyStrategy;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.Audits;
|
||||
import io.atlasmap.v2.Validations;
|
||||
|
||||
public interface AtlasSession {
|
||||
|
||||
@Deprecated
|
||||
Map<String, Object> getProperties();
|
||||
|
||||
Map<String, Object> getSourceProperties();
|
||||
|
||||
Map<String, Object> getTargetProperties();
|
||||
|
||||
AtlasPropertyStrategy getAtlasPropertyStrategy();
|
||||
|
||||
void setAtlasPropertyStrategy(AtlasPropertyStrategy strategy);
|
||||
|
||||
AtlasContext getAtlasContext();
|
||||
|
||||
void setAtlasContext(AtlasContext atlasContext);
|
||||
|
||||
AtlasMapping getMapping();
|
||||
|
||||
Object getDefaultSourceDocument();
|
||||
|
||||
void setDefaultSourceDocument(Object sourceDoc);
|
||||
|
||||
Object getSourceDocument(String docId);
|
||||
|
||||
void setSourceDocument(String docId, Object sourceDoc);
|
||||
|
||||
boolean hasSourceDocument(String docId);
|
||||
|
||||
Map<String, Object> getSourceDocumentMap();
|
||||
|
||||
Object getDefaultTargetDocument();
|
||||
|
||||
void setDefaultTargetDocument(Object targetDoc);
|
||||
|
||||
Object getTargetDocument(String docId);
|
||||
|
||||
void setTargetDocument(String docId, Object targetDoc);
|
||||
|
||||
boolean hasTargetDocument(String docId);
|
||||
|
||||
Map<String, Object> getTargetDocumentMap();
|
||||
|
||||
Validations getValidations();
|
||||
|
||||
void setValidations(Validations validations);
|
||||
|
||||
Audits getAudits();
|
||||
|
||||
void setAudits(Audits audits);
|
||||
|
||||
boolean hasErrors();
|
||||
|
||||
boolean hasWarns();
|
||||
|
||||
Integer errorCount();
|
||||
|
||||
Integer warnCount();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
public class AtlasUnsupportedException extends AtlasException {
|
||||
|
||||
private static final long serialVersionUID = 4276166328541103662L;
|
||||
|
||||
public AtlasUnsupportedException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AtlasUnsupportedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AtlasUnsupportedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AtlasUnsupportedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
public class AtlasValidationException extends AtlasException {
|
||||
|
||||
private static final long serialVersionUID = 6537018220259702613L;
|
||||
|
||||
public AtlasValidationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AtlasValidationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AtlasValidationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AtlasValidationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.Validation;
|
||||
|
||||
public interface AtlasValidationService {
|
||||
|
||||
List<Validation> validateMapping(AtlasMapping mapping);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.builder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.core.ConstantModule;
|
||||
import io.atlasmap.core.DefaultAtlasConversionService;
|
||||
import io.atlasmap.core.DefaultAtlasFieldActionService;
|
||||
import io.atlasmap.core.DefaultAtlasSession;
|
||||
import io.atlasmap.core.PropertyModule;
|
||||
import io.atlasmap.spi.ActionProcessor;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.AtlasModuleMode;
|
||||
import io.atlasmap.v2.Constant;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.PropertyField;
|
||||
|
||||
/**
|
||||
* A part of custom mapping builder API to implement custom mapping logic in Java code.
|
||||
* This class wraps raw {@link Field} and provide some utility methods to introspect
|
||||
* underlying field tree. {@link DefaultAtlasMappingBuilder#read(String, String)}
|
||||
* reads from source document and creates AtlasField.
|
||||
* @see DefaultAtlasMappingBuilder
|
||||
*/
|
||||
public class AtlasField {
|
||||
|
||||
private DefaultAtlasSession session;
|
||||
private DefaultAtlasConversionService conversionService;
|
||||
private DefaultAtlasFieldActionService fieldActionService;
|
||||
private Field rawField;
|
||||
|
||||
public AtlasField(DefaultAtlasSession session) {
|
||||
this.session = session;
|
||||
this.conversionService = session.getAtlasContext().getContextFactory().getConversionService();
|
||||
this.fieldActionService = session.getAtlasContext().getContextFactory().getFieldActionService();
|
||||
}
|
||||
|
||||
public AtlasField read(String docId, String path) throws AtlasException {
|
||||
AtlasModule module = session.resolveModule(docId);
|
||||
if (module == null) {
|
||||
throw new AtlasException(String.format("Source document '%s' doesn't exist", docId));
|
||||
}
|
||||
if (module.getMode() != AtlasModuleMode.SOURCE) {
|
||||
throw new AtlasException(String.format(
|
||||
"Unable to read from %s Document '%s'", module.getMode(), docId));
|
||||
}
|
||||
Field sourceField = module.createField();
|
||||
sourceField.setDocId(docId);
|
||||
sourceField.setPath(path);
|
||||
session.head().setSourceField(sourceField);
|
||||
module.readSourceValue(session);
|
||||
setRawField(sourceField);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AtlasField readConstant(String name) throws AtlasException {
|
||||
ConstantModule module = session.getConstantModule();
|
||||
List<Constant> constants = session.getMapping().getConstants().getConstant();
|
||||
for (Constant constant : constants) {
|
||||
if (constant.getName() != null && constant.getName().equals(name)) {
|
||||
Field sourceField = module.createField();
|
||||
sourceField.setName(constant.getName());
|
||||
sourceField.setFieldType(constant.getFieldType());
|
||||
sourceField.setValue(constant.getValue());
|
||||
session.head().setSourceField(sourceField);
|
||||
module.readSourceValue(session);
|
||||
setRawField(sourceField);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new AtlasException(String.format("Constant '%s' not found", name));
|
||||
}
|
||||
|
||||
public AtlasField readProperty(String scope, String name) throws AtlasException {
|
||||
PropertyModule module = session.getSourcePropertyModule();
|
||||
PropertyField sourceField = module.createField();
|
||||
sourceField.setScope(scope);
|
||||
sourceField.setName(name);
|
||||
session.head().setSourceField(sourceField);
|
||||
module.readSourceValue(session);
|
||||
setRawField(sourceField);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void write(String docId, String path) throws AtlasException {
|
||||
AtlasModule module = session.resolveModule(docId);
|
||||
if (module == null) {
|
||||
throw new AtlasException(String.format("Target document '%s' doesn't exist", docId));
|
||||
}
|
||||
if (module.getMode() != AtlasModuleMode.TARGET) {
|
||||
throw new AtlasException(String.format(
|
||||
"Unable to write to %s Document '%s'", module.getMode(), docId));
|
||||
}
|
||||
Field f = module.createField();
|
||||
f.setDocId(docId);
|
||||
f.setPath(path);
|
||||
session.head().setSourceField(getRawField());
|
||||
session.head().setTargetField(f);
|
||||
module.populateTargetField(session);
|
||||
module.writeTargetValue(session);
|
||||
}
|
||||
|
||||
public void writeProperty(String scope, String name) throws AtlasException {
|
||||
PropertyModule module = session.getTargetPropertyModule();
|
||||
PropertyField f = module.createField();
|
||||
f.setScope(scope);
|
||||
f.setName(name);
|
||||
session.head().setSourceField(getRawField());
|
||||
session.head().setTargetField(f);
|
||||
module.populateTargetField(session);
|
||||
module.writeTargetValue(session);
|
||||
}
|
||||
|
||||
public AtlasField action(String actionName, List<Object> parameters) {
|
||||
Object value = parameters != null && parameters.size() > 1 ? parameters.get(parameters.size()-1) : null;
|
||||
ActionProcessor ap = this.fieldActionService.findActionProcessor(actionName, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Field getRawField() {
|
||||
return this.rawField;
|
||||
}
|
||||
|
||||
public AtlasField setRawField(Field f) {
|
||||
this.rawField = f;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.builder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.api.AtlasMappingBuilder;
|
||||
import io.atlasmap.api.AtlasSession;
|
||||
import io.atlasmap.core.AtlasUtil;
|
||||
import io.atlasmap.core.DefaultAtlasSession;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasFieldActionService;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.SimpleField;
|
||||
|
||||
/**
|
||||
* A base {@code AtlasMappingBuilder} with some common utility methods.
|
||||
* In most cases user can extend this class and just implement {@link #processMapping()}.
|
||||
* @see AtlasField
|
||||
*/
|
||||
public abstract class DefaultAtlasMappingBuilder implements AtlasMappingBuilder {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasMappingBuilder.class);
|
||||
private DefaultAtlasSession session;
|
||||
private AtlasConversionService conversionService;
|
||||
private AtlasFieldActionService fieldActionService;
|
||||
|
||||
public AtlasField read(String docId, String path) throws AtlasException {
|
||||
return new AtlasField(session).read(docId, path);
|
||||
}
|
||||
|
||||
public AtlasField readConstant(String name) throws AtlasException {
|
||||
return new AtlasField(session).readConstant(name);
|
||||
}
|
||||
|
||||
public AtlasField readProperty(String scope, String name) throws AtlasException {
|
||||
return new AtlasField(session).readProperty(scope, name);
|
||||
}
|
||||
|
||||
public void write(String docId, String path, Object value) throws AtlasException {
|
||||
SimpleField source = new SimpleField();
|
||||
if (value != null) {
|
||||
source.setValue(value);
|
||||
source.setFieldType(this.conversionService.fieldTypeFromClass(value.getClass()));
|
||||
}
|
||||
new AtlasField(session).setRawField(source).write(docId, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
try {
|
||||
processMapping();
|
||||
} catch (Exception e) {
|
||||
addAudit(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define custom mapping logic. User can extend this class and implement
|
||||
* custom mapping logic in this method. The thrown Exception will be catched
|
||||
* in {@link #process()} and added as an Audit.
|
||||
* @throws Exception Indicate mapping error to be recorded as an Audit
|
||||
*/
|
||||
public abstract void processMapping() throws Exception;
|
||||
|
||||
@Override
|
||||
public void setAtlasSession(AtlasSession session) throws AtlasException {
|
||||
if (!(session instanceof DefaultAtlasSession)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"This version of MappingBuilder doesn't support %s",
|
||||
session.getClass().getName()));
|
||||
}
|
||||
this.session = (DefaultAtlasSession) session;
|
||||
this.conversionService = session.getAtlasContext().getContextFactory().getConversionService();
|
||||
this.fieldActionService = session.getAtlasContext().getContextFactory().getFieldActionService();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get {@code DefaultAtlasSession}.
|
||||
* @return {@code AtlasSession}.
|
||||
*/
|
||||
public AtlasSession getAtlasSession() {
|
||||
return this.session;
|
||||
};
|
||||
|
||||
public void addAudit(Exception e) {
|
||||
AtlasUtil.addAudit(this.session, this.getClass().getName(),
|
||||
e.getMessage(), AuditStatus.ERROR, null);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class BigDecimalConverter implements AtlasConverter<BigInteger> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(BigDecimal value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(BigDecimal value) {
|
||||
return value != null ? value.toBigInteger() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.BOOLEAN)
|
||||
public Boolean toBoolean(BigDecimal value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.BYTE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.toBigInteger().byteValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.CHAR,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Character toCharacter(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Character.valueOf((char) value.intValueExact());
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.DATE_TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Date toDate(BigDecimal date) throws AtlasConversionException {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long dateLong = date.toBigInteger().longValueExact();
|
||||
if (dateLong >= Instant.MIN.getEpochSecond()) {
|
||||
return Date.from(Instant.ofEpochMilli(dateLong));
|
||||
}
|
||||
return new Date(dateLong);
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", date));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.DOUBLE,
|
||||
concerns = {AtlasConversionConcern.RANGE})
|
||||
public Double toDouble(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Double answer = value.doubleValue();
|
||||
if (answer == Double.NEGATIVE_INFINITY || answer == Double.POSITIVE_INFINITY) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Double.MAX_VALUE or less than Double.MIN_VALUE", value));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.FLOAT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Float toFloat(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Float answer = value.floatValue();
|
||||
if (answer == Float.NEGATIVE_INFINITY || answer == Float.POSITIVE_INFINITY) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Float.MAX_VALUE or less than Float.MIN_VALUE", value));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.INTEGER,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.intValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.DATE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalDate toLocalDate(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.toBigInteger().longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalTime toLocalTime(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.toBigInteger().longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalTime();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.DATE_TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalDateTime toLocalDateTime(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.toBigInteger().longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.LONG,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Long toLong(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.toBigInteger().longValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(BigDecimal value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.SHORT,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Short toShort(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.toBigInteger().shortValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("BigDecimal %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.STRING)
|
||||
public String toString(BigDecimal value) {
|
||||
return value != null ? value.toString() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(BigDecimal value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(BigDecimal value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(BigDecimal value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(BigDecimal value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DECIMAL, targetType = FieldType.DATE_TIME_TZ,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public ZonedDateTime toZonedDateTime(BigDecimal value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault());
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigDecimal %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class BigIntegerConverter implements AtlasConverter<BigInteger> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(BigInteger value) {
|
||||
return value != null ? new BigDecimal(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(BigInteger value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.BOOLEAN)
|
||||
public Boolean toBoolean(BigInteger value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.BYTE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.byteValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.CHAR,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Character toCharacter(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Character.valueOf((char) value.intValueExact());
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.DATE_TIME,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Date toDate(BigInteger date) throws AtlasConversionException {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long dateLong = date.longValueExact();
|
||||
if (dateLong >= Instant.MIN.getEpochSecond()) {
|
||||
return Date.from(Instant.ofEpochMilli(dateLong));
|
||||
}
|
||||
return new Date(dateLong);
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", date));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.DOUBLE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Double toDouble(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Double answer = value.doubleValue();
|
||||
if (answer == Double.NEGATIVE_INFINITY || answer == Double.POSITIVE_INFINITY) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Double.MAX_VALUE or less than Double.MIN_VALUE", value));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.FLOAT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Float toFloat(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Float answer = value.floatValue();
|
||||
if (answer == Float.NEGATIVE_INFINITY || answer == Float.POSITIVE_INFINITY) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Float.MAX_VALUE or less than Float.MIN_VALUE", value));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.INTEGER,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.intValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.DATE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public LocalDate toLocalDate(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.TIME,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public LocalTime toLocalTime(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalTime();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.DATE_TIME,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public LocalDateTime toLocalDateTime(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.LONG,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Long toLong(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.longValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(BigInteger value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.SHORT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return value.shortValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("BigInteger %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.STRING)
|
||||
public String toString(BigInteger value) {
|
||||
return value != null ? value.toString() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(BigInteger value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(BigInteger value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(BigInteger value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(BigInteger value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BIG_INTEGER, targetType = FieldType.DATE_TIME_TZ,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public ZonedDateTime toZonedDateTime(BigInteger value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long longValue = value.longValueExact();
|
||||
return Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault());
|
||||
} catch (ArithmeticException e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"BigInteger %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class BooleanConverter implements AtlasConverter<Boolean> {
|
||||
|
||||
private static final String STRING_VALUES = "true|false";
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Boolean value) {
|
||||
return value != null ? BigDecimal.valueOf(value ? 1 : 0) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Boolean value) {
|
||||
return value != null ? BigInteger.valueOf(value ? 1 : 0) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.BOOLEAN)
|
||||
public Boolean toBoolean(Boolean value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? Boolean.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.BYTE)
|
||||
public Byte toByte(Boolean value) {
|
||||
return value != null ? (byte) (value ? 1 : 0) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.CHAR)
|
||||
public Character toCharacter(Boolean value) {
|
||||
return value != null ? (char) (value ? 1 : 0) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Boolean value) {
|
||||
return value != null ? value ? 1.0d : 0.0d : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Boolean value) {
|
||||
return value != null ? (value ? 1.0f : 0.0f) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.INTEGER)
|
||||
public Integer toInteger(Boolean value) {
|
||||
return value != null ? (value ? 1 : 0) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.LONG)
|
||||
public Long toLong(Boolean value) {
|
||||
return value != null ? (value ? 1L : 0L) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Boolean value) {
|
||||
return toShort(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.SHORT)
|
||||
public Short toShort(Boolean value) {
|
||||
return value != null ? (short) (value ? 1 : 0) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.STRING, concerns = {
|
||||
AtlasConversionConcern.CONVENTION })
|
||||
public String toString(Boolean value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
// TODO optimize/save defaults
|
||||
String format = targetFormat != null && !"".equals(targetFormat) ? targetFormat : STRING_VALUES;
|
||||
String[] values = format.split("\\|");
|
||||
String trueValue = "";
|
||||
String falseValue = "";
|
||||
if (values.length == 2) {
|
||||
trueValue = values[0];
|
||||
falseValue = values[1];
|
||||
} else if (values.length == 1) {
|
||||
trueValue = values[0];
|
||||
}
|
||||
return String.valueOf((value ? trueValue : falseValue));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Boolean value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? CharBuffer.wrap(toString(value, sourceFormat, targetFormat)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Boolean value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? toString(value, sourceFormat, targetFormat) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Boolean value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? new StringBuffer(toString(value, sourceFormat, targetFormat)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BOOLEAN, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Boolean value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? new StringBuilder(toString(value, sourceFormat, targetFormat)) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class ByteConverter implements AtlasConverter<Byte> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Byte value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Byte value) {
|
||||
return value != null ? BigInteger.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.BOOLEAN,
|
||||
concerns = {AtlasConversionConcern.CONVENTION})
|
||||
public Boolean toBoolean(Byte value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.byteValue() != 0;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.BYTE)
|
||||
public Byte toByte(Byte value) {
|
||||
return value != null ? new Byte(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.CHAR)
|
||||
public Character toCharacter(Byte value) {
|
||||
return value != null ? (char) value.byteValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Byte value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value >= Instant.MIN.getEpochSecond()) {
|
||||
return Date.from(Instant.ofEpochMilli(value));
|
||||
}
|
||||
return new Date(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Byte value) {
|
||||
return value != null ? (double) value : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Byte value) {
|
||||
return value != null ? (float) value : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.INTEGER)
|
||||
public Integer toInteger(Byte value) {
|
||||
return value != null ? (int) value : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Byte value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Byte value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Byte value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.LONG)
|
||||
public Long toLong(Byte value) {
|
||||
return value != null ? (long) value : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Byte value) {
|
||||
return toShort(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.SHORT)
|
||||
public Short toShort(Byte value) {
|
||||
return value != null ? (short) value : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.STRING,
|
||||
concerns = {AtlasConversionConcern.CONVENTION})
|
||||
public String toString(Byte value) {
|
||||
return value != null ? String.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Byte value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Byte value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Byte value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Byte value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.BYTE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Byte value) {
|
||||
return Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class CalendarConverter implements AtlasConverter<Calendar> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Calendar calendar) {
|
||||
return calendar != null ? calendar.getTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Calendar calendar) {
|
||||
return calendar == null ? null : DateTimeHelper.toZonedDateTime(calendar);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class CharBufferConverter implements AtlasConverter<CharBuffer> {
|
||||
|
||||
private CharSequenceConverter delegate = new CharSequenceConverter();
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DECIMAL,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigDecimal toBigDecimal(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toBigDecimal(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigInteger toBigInteger(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toBigInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BOOLEAN, concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(CharBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toBoolean(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.FORMAT, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toByte(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.CHAR, concerns = AtlasConversionConcern.RANGE)
|
||||
public Character toCharacter(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toCharacter(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(CharBuffer date, String sourceFormat, String targetFormat) {
|
||||
return delegate.toDate(date, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DOUBLE, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Double toDouble(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toDouble(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.FLOAT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Float toFloat(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toFloat(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.INTEGER, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Integer toInteger(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(CharBuffer value) {
|
||||
return delegate.toLocalDate(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(CharBuffer value) {
|
||||
return delegate.toLocalTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(CharBuffer value) {
|
||||
return delegate.toLocalDateTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.LONG, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Long toLong(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toLong(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.SHORT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Short toShort(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toShort(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(CharBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(CharBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharSequence(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public String toString(CharBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toString(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(CharBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(CharBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuilder(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.NUMBER, concerns = {
|
||||
AtlasConversionConcern.FORMAT })
|
||||
public Number toNumber(CharBuffer value) throws AtlasConversionException {
|
||||
return delegate.toNumber(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(CharBuffer value) {
|
||||
return delegate.toZonedDateTime(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class CharSequenceConverter implements AtlasConverter<CharSequence> {
|
||||
|
||||
private static final Pattern TRUE_PATTERN = Pattern.compile("true|t|yes|y", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DECIMAL,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigDecimal toBigDecimal(CharSequence value) throws AtlasConversionException {
|
||||
try {
|
||||
return value != null ? new BigDecimal(value.toString()) : null;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s cannont be converted to a BigDecimal as it is not in a valid format", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigInteger toBigInteger(CharSequence value) throws AtlasConversionException {
|
||||
try {
|
||||
return value != null ? new BigInteger(value.toString()) : null;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s cannont be converted to a BigInteger as it is not in a valid format", value));
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BOOLEAN, concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(CharSequence value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// string expression of true?
|
||||
Pattern pattern;
|
||||
if (sourceFormat != null && !sourceFormat.isEmpty()) {
|
||||
pattern = Pattern.compile(sourceFormat, Pattern.CASE_INSENSITIVE);
|
||||
} else {
|
||||
pattern = TRUE_PATTERN;
|
||||
}
|
||||
if (pattern.matcher(value).matches()) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
// then try C like numeric translation
|
||||
try {
|
||||
Number n = NumberFormat.getInstance().parse(value.toString());
|
||||
if (n.intValue() == 0) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
} catch (ParseException e) {
|
||||
e.getMessage(); // ignore
|
||||
}
|
||||
|
||||
// false by default
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.FORMAT, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Byte.parseByte(value.toString());
|
||||
} catch (NumberFormatException nfex) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(value.toString());
|
||||
if (bd.compareTo(new BigDecimal(Byte.MIN_VALUE)) < 0
|
||||
|| bd.compareTo(new BigDecimal(Byte.MAX_VALUE)) > 0) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
return bd.byteValue();
|
||||
} catch (NumberFormatException nfe2) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s cannont be converted to a Byte as it is not in a numerical format", value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.CHAR, concerns = AtlasConversionConcern.RANGE)
|
||||
public Character toCharacter(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
// empty or greater than 1 char String throws Exception
|
||||
if (value.toString().isEmpty() || value.length() > 1) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("String '%s' is either empty or greater than one character long", value));
|
||||
} else if (value.charAt(0) < Character.MIN_VALUE || value.charAt(0) > Character.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
return value.charAt(0);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(CharSequence date, String sourceFormat, String targetFormat) {
|
||||
|
||||
DateTimeFormatter formater = sourceFormat != null ? DateTimeFormatter.ofPattern(sourceFormat)
|
||||
: DateTimeFormatter.ISO_ZONED_DATE_TIME;
|
||||
return Date.from(ZonedDateTime.parse(date, formater).toInstant());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DOUBLE, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Double toDouble(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String str = value.toString();
|
||||
double parsedDouble = 0.0d;
|
||||
try {
|
||||
parsedDouble = Double.parseDouble(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new AtlasConversionException(nfe);
|
||||
}
|
||||
|
||||
double absParsedDouble = Math.abs(parsedDouble);
|
||||
if (absParsedDouble == 0.0d) {
|
||||
return parsedDouble;
|
||||
}
|
||||
if (absParsedDouble < Double.MIN_VALUE || absParsedDouble > Double.MAX_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format(
|
||||
"String %s is greater than Double.MAX_VALUE or less than Double.MIN_VALUE",
|
||||
str));
|
||||
}
|
||||
|
||||
return parsedDouble;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.FLOAT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Float toFloat(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String str = value.toString();
|
||||
float parsedFloat = 0.0f;
|
||||
try {
|
||||
parsedFloat = Float.parseFloat(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new AtlasConversionException(nfe);
|
||||
}
|
||||
|
||||
float absParsedFloat = Math.abs(parsedFloat);
|
||||
if (absParsedFloat == 0.0f) {
|
||||
return parsedFloat;
|
||||
}
|
||||
|
||||
if (absParsedFloat < Float.MIN_VALUE || absParsedFloat > Float.MAX_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format(
|
||||
"String %s is greater than Float.MAX_VALUE or less than Float.MIN_VALUE",
|
||||
str));
|
||||
}
|
||||
|
||||
return Float.valueOf(str);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.INTEGER, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Integer toInteger(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String str = value.toString();
|
||||
Integer i = null;
|
||||
try {
|
||||
i = Integer.parseInt(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(str);
|
||||
if (bd.compareTo(new BigDecimal(Integer.MIN_VALUE)) < 0
|
||||
|| bd.compareTo(new BigDecimal(Integer.MAX_VALUE)) > 0) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", str));
|
||||
}
|
||||
i = bd.intValue();
|
||||
} catch (NumberFormatException nfe2) {
|
||||
throw new AtlasConversionException(nfe);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(CharSequence value) {
|
||||
return value != null ? LocalDate.parse(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(CharSequence value) {
|
||||
return value != null ? LocalTime.parse(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(CharSequence value) {
|
||||
return value != null ? LocalDateTime.parse(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.LONG, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Long toLong(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String str = value.toString();
|
||||
Long l = null;
|
||||
try {
|
||||
l = Long.parseLong(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(str);
|
||||
if (bd.compareTo(new BigDecimal(Long.MIN_VALUE)) < 0
|
||||
|| bd.compareTo(new BigDecimal(Long.MAX_VALUE)) > 0) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
l = bd.longValue();
|
||||
} catch (NumberFormatException nfe2) {
|
||||
throw new AtlasConversionException(nfe);
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.SHORT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Short toShort(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String str = value.toString();
|
||||
Short shortty = null;
|
||||
try {
|
||||
shortty = Short.parseShort(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(str);
|
||||
if (bd.compareTo(new BigDecimal(Short.MIN_VALUE)) < 0
|
||||
|| bd.compareTo(new BigDecimal(Short.MAX_VALUE)) > 0) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("String %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", str));
|
||||
}
|
||||
shortty = bd.shortValue();
|
||||
} catch (NumberFormatException nfe2) {
|
||||
throw new AtlasConversionException(nfe2);
|
||||
}
|
||||
}
|
||||
return shortty;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(CharSequence value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return CharBuffer.wrap(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(CharSequence value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return new String(value.toString());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public String toString(CharSequence value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return new String(value.toString());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(CharSequence value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return new StringBuffer(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(CharSequence value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return new StringBuilder(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.NUMBER, concerns = {
|
||||
AtlasConversionConcern.FORMAT })
|
||||
public Number toNumber(CharSequence value) throws AtlasConversionException {
|
||||
if (value == null || value.toString().trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String str = value.toString();
|
||||
if (str.matches("\\d+")) {
|
||||
return new BigInteger(str);
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(str);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new AtlasConversionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(CharSequence value) {
|
||||
return value != null ? ZonedDateTime.parse(value) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class CharacterConverter implements AtlasConverter<Character> {
|
||||
|
||||
private static final String TRUE_REGEX = "t|T|y|Y|[1-9]";
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Character value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Character value) {
|
||||
return value != null ? BigInteger.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.BOOLEAN, concerns = {
|
||||
AtlasConversionConcern.CONVENTION })
|
||||
public Boolean toBoolean(Character value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String regex = sourceFormat != null && !"".equals(sourceFormat) ? sourceFormat : TRUE_REGEX;
|
||||
if (Character.toString(value).matches(regex)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE })
|
||||
public Byte toByte(Character value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.charValue() > Byte.MAX_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Character value %s is greater than BYTE.MAX_VALUE", value));
|
||||
}
|
||||
return (byte) value.charValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.CHAR)
|
||||
public Character toCharacter(Character value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
// we want new Character from the value
|
||||
return new Character(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Character value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Double.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Character value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Float.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.INTEGER)
|
||||
public Integer toInteger(Character value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.LONG)
|
||||
public Long toLong(Character value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Long.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Character value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.SHORT, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.CONVENTION })
|
||||
public Short toShort(Character value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
// only care if the char is larger than the short MAX
|
||||
if (value > Short.MAX_VALUE) {
|
||||
throw new AtlasConversionException();
|
||||
}
|
||||
return (short) value.charValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.STRING)
|
||||
public String toString(Character value, String sourceFormat, String targetFormat) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Character value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? CharBuffer.wrap(toString(value, sourceFormat, targetFormat)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Character value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? toString(value, sourceFormat, targetFormat) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Character value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? new StringBuffer(toString(value, sourceFormat, targetFormat)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.CHAR, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Character value, String sourceFormat, String targetFormat) {
|
||||
return value != null ? new StringBuilder(toString(value, sourceFormat, targetFormat)) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class DateConverter implements AtlasConverter<Date> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Date date) {
|
||||
return BigDecimal.valueOf(date.getTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Date date) {
|
||||
return BigInteger.valueOf(date.getTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.BYTE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(Date value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = value.getTime();
|
||||
if (longValue < Byte.MIN_VALUE || longValue > Byte.MAX_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalDateTime %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.byteValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(date.getTime());
|
||||
return calendar;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Date value) {
|
||||
return value != null ? Double.valueOf(value.getTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Date value) {
|
||||
return value != null ? Float.valueOf(value.getTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.INTEGER,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(Date value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = value.getTime();
|
||||
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Date %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(Date date, String sourceFormat, String targetFormat) {
|
||||
return DateTimeHelper.convertDateToGregorianCalendar(date, sourceFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Date date, String sourceFormat, String targetFormat) {
|
||||
return DateTimeHelper.convertDateToLocalDate(date, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Date date, String sourceFormat, String targetFormat) {
|
||||
return DateTimeHelper.convertDateToLocalDateTime(date, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Date date, String sourceFormat, String targetFormat) {
|
||||
return DateTimeHelper.convertDateToLocalTime(date, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.LONG)
|
||||
public Long toLong(Date date) {
|
||||
return date.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Date date) {
|
||||
return date.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.SHORT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(Date value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = value.getTime();
|
||||
if (longValue > Short.MAX_VALUE || longValue < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Date %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE)
|
||||
public java.sql.Date toSqlDate(Date date, String sourceFormat, String targetFormat) {
|
||||
return DateTimeHelper.convertDateToSqlDate(date, sourceFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.TIME)
|
||||
public Time toSqlTime(Date date, String sourceFormat, String targetFormat) {
|
||||
return DateTimeHelper.convertDateToTime(date, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public String toString(Date date) {
|
||||
// by default Instant.toString returns an ISO-8601 representation of the instant
|
||||
return date.toInstant().toString();
|
||||
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Date value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Date value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Date value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Date value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public Timestamp toSqlTimestamp(Date date) {
|
||||
return Timestamp.from(date.toInstant());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Date date) {
|
||||
return DateTimeHelper.toZonedDateTime(date, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class DateTimeHelper {
|
||||
|
||||
public static GregorianCalendar convertDateToGregorianCalendar(Date date, String timeZone) {
|
||||
return GregorianCalendar.from(DateTimeHelper.toZonedDateTime(date, timeZone));
|
||||
}
|
||||
|
||||
public static Date convertSqlDateToDate(java.sql.Date date, String timeZone) {
|
||||
return Date.from(date.toLocalDate().atStartOfDay(zoneId(timeZone)).toInstant());
|
||||
}
|
||||
|
||||
public static java.sql.Date convertDateToSqlDate(Date date, String timeZone) {
|
||||
return java.sql.Date.valueOf(DateTimeHelper.convertDateToLocalDate(date, timeZone));
|
||||
}
|
||||
|
||||
public static Date convertSqlTimeToDate(Time time, String timeZone) {
|
||||
return DateTimeHelper.convertLocalTimeToDate(time.toLocalTime(), timeZone); // ?
|
||||
}
|
||||
|
||||
public static LocalDate convertDateToLocalDate(Date date, String timeZone) {
|
||||
return LocalDateTime.ofInstant(date.toInstant(), zoneId(timeZone)).toLocalDate();
|
||||
}
|
||||
|
||||
public static Date convertLocalTimeToDate(LocalTime localTime, String timeZone) {
|
||||
return Date.from(localTime.atDate(LocalDate.now()).atZone(zoneId(timeZone)).toInstant());
|
||||
}
|
||||
|
||||
public static LocalTime convertDateToLocalTime(Date date, String timeZone) {
|
||||
return LocalDateTime.ofInstant(date.toInstant(), zoneId(timeZone)).toLocalTime();
|
||||
}
|
||||
|
||||
public static Date convertLocalDateTimeToDate(LocalDateTime localDateTime, String timeZone) {
|
||||
return Date.from(localDateTime.atZone(zoneId(timeZone)).toInstant());
|
||||
}
|
||||
|
||||
public static LocalDateTime convertDateToLocalDateTime(Date date, String timeZone) {
|
||||
return LocalDateTime.ofInstant(date.toInstant(), zoneId(timeZone));
|
||||
}
|
||||
|
||||
public static Time convertDateToTime(Date date, String timeZone) {
|
||||
return Time.valueOf(LocalDateTime.ofInstant(date.toInstant(), zoneId(timeZone)).toLocalTime());
|
||||
}
|
||||
|
||||
public static ZonedDateTime toZonedDateTime(Calendar calendar) {
|
||||
return ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
|
||||
}
|
||||
|
||||
public static ZonedDateTime toZonedDateTime(Date date, String timeZone) {
|
||||
return ZonedDateTime.ofInstant(date.toInstant(), zoneId(timeZone));
|
||||
}
|
||||
|
||||
public static ZonedDateTime toZonedDateTime(LocalDate date, String timeZone) {
|
||||
return date.atStartOfDay(zoneId(timeZone));
|
||||
}
|
||||
|
||||
public static ZonedDateTime toZonedDateTime(LocalTime time, String timeZone) {
|
||||
return toZonedDateTime(time.atDate(LocalDate.now()), timeZone);
|
||||
}
|
||||
|
||||
public static ZonedDateTime toZonedDateTime(LocalDateTime date, String timeZone) {
|
||||
return date.atZone(zoneId(timeZone));
|
||||
}
|
||||
|
||||
private static ZoneId zoneId(String timeZone) {
|
||||
return timeZone != null ? ZoneId.of(timeZone) : ZoneId.systemDefault();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasUnsupportedException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class DoubleConverter implements AtlasConverter<Double> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Double value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FRACTIONAL_PART)
|
||||
public BigInteger toBigInteger(Double value) {
|
||||
return value != null ? BigDecimal.valueOf(value).toBigInteger() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.BOOLEAN, concerns = {
|
||||
AtlasConversionConcern.CONVENTION })
|
||||
public Boolean toBoolean(Double value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value == 0.0 ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.BYTE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value % 1 == 0 && value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
||||
return value.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(new AtlasUnsupportedException(String.format(
|
||||
"Double %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE or is not a whole number",
|
||||
value)));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.CHAR,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Character toCharacter(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Double %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.DATE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Date toDate(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Double %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return new Date(value.longValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Double value) {
|
||||
return value != null ? Double.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.FLOAT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Float toFloat(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
double absValue = Math.abs(value);
|
||||
if (absValue > Float.MAX_VALUE || (absValue < Float.MIN_VALUE && value != 0)) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Double %s is greater than Float.MAX_VALUE or less than Float.MIN_VALUE", value));
|
||||
}
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.INTEGER,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Integer toInteger(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Double %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.DATE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalDate toLocalDate(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Double %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalTime toLocalTime(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Double %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault()).toLocalTime();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.DATE_TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalDateTime toLocalDateTime(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Double %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.LONG, concerns = AtlasConversionConcern.RANGE)
|
||||
public Long toLong(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Double %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Double value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.SHORT, concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Double %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return value.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.STRING)
|
||||
public String toString(Double value) {
|
||||
return value != null ? String.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Double value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Double value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Double value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Double value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DOUBLE, targetType = FieldType.DATE_TIME_TZ,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public ZonedDateTime toZonedDateTime(Double value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Double %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasUnsupportedException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class FloatConverter implements AtlasConverter<Float> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Float value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FRACTIONAL_PART)
|
||||
public BigInteger toBigInteger(Float value) {
|
||||
return value != null ? BigDecimal.valueOf(value).toBigInteger() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.BOOLEAN, concerns = {
|
||||
AtlasConversionConcern.CONVENTION })
|
||||
public Boolean toBoolean(Float value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value == 0.0) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE })
|
||||
public Byte toByte(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value % 1 == 0 && value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
||||
return value.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(new AtlasUnsupportedException(String.format(
|
||||
"Float %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE or is not a whole number",
|
||||
value)));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.CHAR, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.CONVENTION })
|
||||
public Character toCharacter(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Float %s is greater than Character.MAX_VALUE or is less than Character.MIN_VALUE", value));
|
||||
}
|
||||
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.DATE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Date toDate(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Float %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return new Date(value.longValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Float value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.doubleValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Float value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
// we want a copy of value
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.INTEGER, concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Float %s is greater than Integer.MAX_VALUE or is less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.DATE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalDate toLocalDate(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Float %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalTime toLocalTime(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Float %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault()).toLocalTime();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.DATE_TIME,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public LocalDateTime toLocalDateTime(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Float %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.LONG,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Long toLong(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Float %s is greater than Long.MAX_VALUE or is less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Float value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.SHORT, concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Float %s is greater than Short.MAX_VALUE or is less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return value.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.STRING)
|
||||
public String toString(Float value) {
|
||||
return value != null ? String.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Float value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Float value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Float value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Float value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.FLOAT, targetType = FieldType.DATE_TIME_TZ,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public ZonedDateTime toZonedDateTime(Float value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Float %s is greater than Long.MAX_VALUE or less than Long.MIN_VALUE", value));
|
||||
}
|
||||
return Instant.ofEpochMilli(value.longValue()).atZone(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class GregorianCalendarConverter implements AtlasConverter<GregorianCalendar> {
|
||||
|
||||
private ZonedDateTimeConverter zdtConverter = new ZonedDateTimeConverter();
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(GregorianCalendar calendar) {
|
||||
return calendar;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(GregorianCalendar calendar) {
|
||||
return zdtConverter.toDate(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(GregorianCalendar calendar) {
|
||||
return zdtConverter.toLocalDate(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(GregorianCalendar calendar) {
|
||||
return zdtConverter.toLocalDateTime(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(GregorianCalendar calendar) {
|
||||
return zdtConverter.toLocalTime(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE)
|
||||
public java.sql.Date toSqlDate(GregorianCalendar calendar) {
|
||||
return zdtConverter.toSqlDate(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.TIME)
|
||||
public java.sql.Time toSqlTime(GregorianCalendar calendar) {
|
||||
return zdtConverter.toSqlTime(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME)
|
||||
public java.sql.Timestamp toSqlTimestamp(GregorianCalendar calendar) {
|
||||
return zdtConverter.toSqlTimestamp(calendar.toZonedDateTime());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZoneDateTime(GregorianCalendar calendar) {
|
||||
return calendar.toZonedDateTime();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasUnsupportedException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class IntegerConverter implements AtlasConverter<Integer> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Integer value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Integer value) {
|
||||
return value != null ? BigInteger.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.BOOLEAN, concerns = {
|
||||
AtlasConversionConcern.CONVENTION })
|
||||
public Boolean toBoolean(Integer value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value == 0 ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.BYTE, concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(Integer value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
||||
return value.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(new AtlasUnsupportedException(
|
||||
String.format("Integer %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value)));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.CHAR, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.CONVENTION })
|
||||
public Character toCharacter(Integer value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Integer %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Integer value) {
|
||||
if (value >= Instant.MIN.getEpochSecond()) {
|
||||
return Date.from(Instant.ofEpochMilli(value));
|
||||
}
|
||||
return new Date(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Integer value) {
|
||||
return value != null ? value.doubleValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.FLOAT, concerns = AtlasConversionConcern.RANGE)
|
||||
public Float toFloat(Integer value) {
|
||||
return value != null ? value.floatValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.INTEGER)
|
||||
public Integer toInteger(Integer value) {
|
||||
return value != null ? Integer.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Integer value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Integer value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Integer value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.LONG)
|
||||
public Long toLong(Integer value) {
|
||||
return value != null ? value.longValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.SHORT, concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(Integer value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Integer %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return value.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.STRING)
|
||||
public String toString(Integer value) {
|
||||
return value != null ? String.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Integer value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Integer value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Integer value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Integer value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Integer value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.INTEGER, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Integer value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class LocalDateConverter implements AtlasConverter<LocalDate> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(LocalDate value) {
|
||||
return value != null ? BigDecimal.valueOf(getStartEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(LocalDate value) {
|
||||
return value != null ? BigInteger.valueOf(getStartEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.BYTE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(LocalDate value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getStartEpochMilli(value);
|
||||
if (longValue >= Byte.MIN_VALUE && longValue <= Byte.MAX_VALUE) {
|
||||
return longValue.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalDate %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(LocalDate value) {
|
||||
return value != null ? GregorianCalendar.from(value.atStartOfDay(ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(LocalDate value) {
|
||||
return value != null ? new Date(getStartEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(LocalDate value) {
|
||||
return value != null ? getStartEpochMilli(value).doubleValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(LocalDate value) {
|
||||
return value != null ? getStartEpochMilli(value).floatValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(LocalDate value) {
|
||||
return value != null ? GregorianCalendar.from(value.atStartOfDay(ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.INTEGER,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(LocalDate value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getStartEpochMilli(value);
|
||||
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("LocalDate %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(LocalDate value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(LocalDate value) {
|
||||
return value != null ? value.atStartOfDay() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(LocalDate value) {
|
||||
return value != null ? value.atStartOfDay().toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.LONG)
|
||||
public Long toLong(LocalDate value) {
|
||||
return value != null ? getStartEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.SHORT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(LocalDate value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getStartEpochMilli(value);
|
||||
if (longValue > Short.MAX_VALUE || longValue < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalDate %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.STRING)
|
||||
public String toString(LocalDate value) {
|
||||
return value != null ? value.toString() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(LocalDate value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(LocalDate value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(LocalDate value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(LocalDate value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(LocalDate value) {
|
||||
return value != null ? getStartEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE)
|
||||
public java.sql.Date toSqlDate(LocalDate value) {
|
||||
return java.sql.Date.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME)
|
||||
public java.sql.Timestamp toSqlTimestamp(LocalDate value) {
|
||||
return value != null ? java.sql.Timestamp.valueOf(value.atStartOfDay()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(LocalDate value) {
|
||||
return value != null ? value.atStartOfDay(ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
private Long getStartEpochMilli(LocalDate value) {
|
||||
return value != null ? value.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class LocalDateTimeConverter implements AtlasConverter<LocalDateTime> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(LocalDateTime value) {
|
||||
return value != null ? BigDecimal.valueOf(getEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(LocalDateTime value) {
|
||||
return value != null ? BigInteger.valueOf(getEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.BYTE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(LocalDateTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getEpochMilli(value);
|
||||
if (longValue >= Byte.MIN_VALUE && longValue <= Byte.MAX_VALUE) {
|
||||
return longValue.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalDateTime %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(LocalDateTime value) {
|
||||
return value != null ? GregorianCalendar.from(value.atZone(ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(LocalDateTime value) {
|
||||
return value != null ? new Date(getEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(LocalDateTime value) {
|
||||
return value != null ? getEpochMilli(value).doubleValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(LocalDateTime value) {
|
||||
return value != null ? getEpochMilli(value).floatValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(LocalDateTime value) {
|
||||
return value != null ? GregorianCalendar.from(value.atZone(ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.INTEGER,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(LocalDateTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getEpochMilli(value);
|
||||
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("LocalDateTime %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(LocalDateTime value) {
|
||||
return value != null ? value.toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(LocalDateTime value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(LocalDateTime value) {
|
||||
return value != null ? value.toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.LONG)
|
||||
public Long toLong(LocalDateTime value) {
|
||||
return value != null ? getEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.SHORT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(LocalDateTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getEpochMilli(value);
|
||||
if (longValue > Short.MAX_VALUE || longValue < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalDateTime %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public String toString(LocalDateTime value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(LocalDateTime value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(LocalDateTime value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(LocalDateTime value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(LocalDateTime value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(LocalDateTime value) {
|
||||
return value != null ? getEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE)
|
||||
public java.sql.Date toSqlDate(LocalDateTime value) {
|
||||
return value != null ? java.sql.Date.valueOf(value.toLocalDate()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.TIME)
|
||||
public java.sql.Time toSqlTime(LocalDateTime value) {
|
||||
return value != null ? java.sql.Time.valueOf(value.toLocalTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public java.sql.Timestamp toSqlTimestamp(LocalDateTime value) {
|
||||
return value != null ? java.sql.Timestamp.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(LocalDateTime value) {
|
||||
return value != null ? value.atZone(ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
private Long getEpochMilli(LocalDateTime value) {
|
||||
return value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class LocalTimeConverter implements AtlasConverter<LocalTime> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(LocalTime value) {
|
||||
return value != null ? BigDecimal.valueOf(getTodaysEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(LocalTime value) {
|
||||
return value != null ? BigInteger.valueOf(getTodaysEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.BYTE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(LocalTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getTodaysEpochMilli(value);
|
||||
if (longValue >= Byte.MIN_VALUE && longValue <= Byte.MAX_VALUE) {
|
||||
return longValue.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalTime %s of today is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(LocalTime value) {
|
||||
return value != null ? GregorianCalendar.from(value.atDate(LocalDate.now()).atZone(ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(LocalTime value) {
|
||||
return value != null ? new Date(getTodaysEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(LocalTime value) {
|
||||
return value != null ? getTodaysEpochMilli(value).doubleValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(LocalTime value) {
|
||||
return value != null ? getTodaysEpochMilli(value).floatValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(LocalTime value) {
|
||||
return value != null ? GregorianCalendar.from(value.atDate(LocalDate.now()).atZone(ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.INTEGER,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(LocalTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getTodaysEpochMilli(value);
|
||||
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("LocalTime nano-of-day %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", longValue));
|
||||
}
|
||||
return longValue.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(LocalTime value) {
|
||||
return value != null ? value.atDate(LocalDate.now()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(LocalTime value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.LONG)
|
||||
public Long toLong(LocalTime value) {
|
||||
return value != null ? getTodaysEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.SHORT,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(LocalTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getTodaysEpochMilli(value);
|
||||
if (longValue > Short.MAX_VALUE || longValue < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalTime nano-of-day %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", longValue));
|
||||
}
|
||||
return longValue.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.STRING)
|
||||
public String toString(LocalTime value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(LocalTime value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(LocalTime value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(LocalTime value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(LocalTime value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(LocalTime value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return getTodaysEpochMilli(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.TIME)
|
||||
public java.sql.Time toSqlTime(LocalTime value) {
|
||||
return java.sql.Time.valueOf(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME)
|
||||
public java.sql.Timestamp toSqlTimestamp(LocalTime value) {
|
||||
return value != null ? java.sql.Timestamp.valueOf(value.atDate(LocalDate.now())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(LocalTime value) {
|
||||
return value != null ? value.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
private Long getTodaysEpochMilli(LocalTime value) {
|
||||
return value.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasUnsupportedException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class LongConverter implements AtlasConverter<Long> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Long value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Long value) {
|
||||
return value != null ? BigInteger.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.BOOLEAN,
|
||||
concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(Long value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value == 0L ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.BYTE,
|
||||
concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(Long value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
||||
return value.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(new AtlasUnsupportedException(
|
||||
String.format("Long %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value)));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.CHAR, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.CONVENTION })
|
||||
public Character toCharacter(Long value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Long %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Date toDate(Long date) {
|
||||
if (date >= Instant.MIN.getEpochSecond()) {
|
||||
return Date.from(Instant.ofEpochMilli(date));
|
||||
}
|
||||
return new Date(date);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Long value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.doubleValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Long value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.INTEGER, concerns = AtlasConversionConcern.RANGE)
|
||||
public Integer toInteger(Long value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Long %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Long value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Long value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Long value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.LONG)
|
||||
public Long toLong(Long value) {
|
||||
return value != null ? new Long(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.SHORT, concerns = AtlasConversionConcern.RANGE)
|
||||
public Short toShort(Long value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("Long %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return value.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Long value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.STRING)
|
||||
public String toString(Long value) {
|
||||
return value != null ? String.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Long value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Long value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Long value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Long value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.LONG, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Long value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class NumberConverter implements AtlasConverter<Number> {
|
||||
private BigDecimalConverter bigDecimalConverter = new BigDecimalConverter();
|
||||
private BigIntegerConverter bigIntegerConverter = new BigIntegerConverter();
|
||||
private ByteConverter byteConverter = new ByteConverter();
|
||||
private DoubleConverter doubleConverter = new DoubleConverter();
|
||||
private FloatConverter floatConverter = new FloatConverter();
|
||||
private IntegerConverter integerConverter = new IntegerConverter();
|
||||
private LongConverter longConverter = new LongConverter();
|
||||
private ShortConverter shortConverter = new ShortConverter();
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Number value) throws AtlasConversionException {
|
||||
return invoke(value, BigDecimal.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Number value) throws AtlasConversionException {
|
||||
return invoke(value, BigInteger.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.BOOLEAN)
|
||||
public Boolean toBoolean(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Boolean.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.BYTE)
|
||||
public Byte toByte(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Byte.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.CHAR)
|
||||
public Character toCharacter(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Character.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Date.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Double.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Float.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.INTEGER)
|
||||
public Integer toInteger(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Integer.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Number value) throws AtlasConversionException {
|
||||
return invoke(value, LocalDate.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Number value) throws AtlasConversionException {
|
||||
return invoke(value, LocalTime.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Number value) throws AtlasConversionException {
|
||||
return invoke(value, LocalDateTime.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.LONG)
|
||||
public Long toLong(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Long.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Number value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.SHORT)
|
||||
public Short toShort(Number value) throws AtlasConversionException {
|
||||
return invoke(value, Short.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.STRING)
|
||||
public String toString(Number value) throws AtlasConversionException {
|
||||
return invoke(value, String.class);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Number value) throws AtlasConversionException {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Number value) throws AtlasConversionException {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Number value) throws AtlasConversionException {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Number value) throws AtlasConversionException {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.NUMBER, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Number value) throws AtlasConversionException {
|
||||
return invoke(value, ZonedDateTime.class);
|
||||
}
|
||||
|
||||
private <T> T invoke(Number object, Class<T> returnType) throws AtlasConversionException {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (returnType.isInstance(object)) {
|
||||
return returnType.cast(object);
|
||||
}
|
||||
|
||||
try {
|
||||
if (object instanceof BigDecimal) {
|
||||
Method m = bigDecimalConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(bigDecimalConverter, object));
|
||||
|
||||
} else if (object instanceof BigInteger) {
|
||||
Method m = bigIntegerConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(bigIntegerConverter, object));
|
||||
|
||||
} else if (object instanceof Byte) {
|
||||
Method m = byteConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(byteConverter, object));
|
||||
|
||||
} else if (object instanceof Double) {
|
||||
Method m = doubleConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(doubleConverter, object));
|
||||
|
||||
} else if (object instanceof Float) {
|
||||
Method m = floatConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(floatConverter, object));
|
||||
|
||||
} else if (object instanceof Integer) {
|
||||
Method m = integerConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(integerConverter, object));
|
||||
|
||||
} else if (object instanceof Long) {
|
||||
Method m = longConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(longConverter, object));
|
||||
|
||||
} else if (object instanceof Short) {
|
||||
Method m = shortConverter.getClass().getDeclaredMethod(
|
||||
"to" + returnType.getSimpleName(),
|
||||
object.getClass());
|
||||
return returnType.cast(m.invoke(shortConverter, object));
|
||||
|
||||
} else {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"Unsupported Number type '%s'", object.getClass().getName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AtlasConversionException(String.format(
|
||||
"No converter found from='%s' to='%s'", object.getClass().getName(), returnType.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasUnsupportedException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class ShortConverter implements AtlasConverter<Short> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.DECIMAL)
|
||||
public BigDecimal toBigDecimal(Short value) {
|
||||
return value != null ? BigDecimal.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.BIG_INTEGER)
|
||||
public BigInteger toBigInteger(Short value) {
|
||||
return value != null ? BigInteger.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.BOOLEAN, concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(Short value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value == 0 ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.BYTE, concerns = AtlasConversionConcern.RANGE)
|
||||
public Byte toByte(Short value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
||||
return value.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(new AtlasUnsupportedException(
|
||||
String.format("Short %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value)));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.CHAR, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.CONVENTION })
|
||||
public Character toCharacter(Short value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("Short %s is greater than Character.MAX_VALUE or less than Character.MIN_VALUE", value));
|
||||
}
|
||||
return Character.valueOf((char) value.intValue());
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Short value) {
|
||||
if (value >= Instant.MIN.getEpochSecond()) {
|
||||
return Date.from(Instant.ofEpochMilli(value));
|
||||
}
|
||||
return new Date(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.DOUBLE)
|
||||
public Double toDouble(Short value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.doubleValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.FLOAT)
|
||||
public Float toFloat(Short value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.INTEGER)
|
||||
public Integer toInteger(Short value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Short value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Short value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Short value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.LONG)
|
||||
public Long toLong(Short value) {
|
||||
return value != null ? value.longValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.NUMBER)
|
||||
public Number toNumber(Short value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.SHORT)
|
||||
public Short toShort(Short value) {
|
||||
return value != null ? new Short(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.STRING)
|
||||
public String toString(Short value) {
|
||||
return value != null ? String.valueOf(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(Short value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(Short value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(Short value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(Short value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.SHORT, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Short value) {
|
||||
return value != null ? Instant.ofEpochMilli(value).atZone(ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class SqlDateConverter implements AtlasConverter<java.sql.Date> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(java.sql.Date date) {
|
||||
return date != null ? GregorianCalendar.from(ZonedDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(java.sql.Date date, String sourceFormat, String targetFormat) {
|
||||
return date != null ? DateTimeHelper.convertSqlDateToDate(date, sourceFormat) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(java.sql.Date date) {
|
||||
return date != null ? GregorianCalendar.from(ZonedDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(java.sql.Date date) {
|
||||
return date != null ? date.toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(java.sql.Date date) {
|
||||
return date != null ? date.toLocalDate().atStartOfDay() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME)
|
||||
public java.sql.Timestamp toSqlTimestamp(java.sql.Date date) {
|
||||
return date != null ? new java.sql.Timestamp(date.getTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(java.sql.Date date) {
|
||||
return date != null ? ZonedDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class SqlTimeConverter implements AtlasConverter<Time> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? GregorianCalendar.from(ZonedDateTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? new Date(time.getTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? GregorianCalendar.from(ZonedDateTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? time.toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? time.toLocalTime().atDate(LocalDate.now()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME)
|
||||
public Timestamp toSqlTimestamp(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? new Timestamp(time.getTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Time time, String sourceFormat, String targetFormat) {
|
||||
return time != null ? ZonedDateTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class SqlTimestampConverter implements AtlasConverter<Timestamp> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(Timestamp timestamp) {
|
||||
return timestamp != null ? GregorianCalendar.from(ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(Timestamp timestamp) {
|
||||
return timestamp != null ? Date.from(timestamp.toInstant()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(Timestamp timestamp) {
|
||||
return timestamp != null ? GregorianCalendar.from(ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.systemDefault())) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(Timestamp timestamp) {
|
||||
return timestamp != null ? timestamp.toLocalDateTime().toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(Timestamp timestamp) {
|
||||
return timestamp != null ? timestamp.toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(Timestamp timestamp) {
|
||||
return timestamp != null ? timestamp.toLocalDateTime().toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE)
|
||||
public java.sql.Date toSqlDate(Timestamp timestamp) {
|
||||
return timestamp != null ? java.sql.Date.valueOf(timestamp.toLocalDateTime().toLocalDate()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.TIME)
|
||||
public java.sql.Time toSqlTime(Timestamp timestamp) {
|
||||
return timestamp != null ? java.sql.Time.valueOf(timestamp.toLocalDateTime().toLocalTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(Timestamp timestamp) {
|
||||
return timestamp != null ? ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.systemDefault()) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class StringBufferConverter implements AtlasConverter<StringBuffer> {
|
||||
|
||||
private CharSequenceConverter delegate = new CharSequenceConverter();
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DECIMAL,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigDecimal toBigDecimal(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toBigDecimal(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigInteger toBigInteger(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toBigInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BOOLEAN, concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(StringBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toBoolean(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.FORMAT, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toByte(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.CHAR, concerns = AtlasConversionConcern.RANGE)
|
||||
public Character toCharacter(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toCharacter(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(StringBuffer date, String sourceFormat, String targetFormat) {
|
||||
return delegate.toDate(date, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DOUBLE, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Double toDouble(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toDouble(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.FLOAT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Float toFloat(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toFloat(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.INTEGER, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Integer toInteger(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(StringBuffer value) {
|
||||
return delegate.toLocalDate(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(StringBuffer value) {
|
||||
return delegate.toLocalTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(StringBuffer value) {
|
||||
return delegate.toLocalDateTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.LONG, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Long toLong(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toLong(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.SHORT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Short toShort(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toShort(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(StringBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(StringBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharSequence(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public String toString(StringBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toString(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(StringBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(StringBuffer value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuilder(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.NUMBER, concerns = {
|
||||
AtlasConversionConcern.FORMAT })
|
||||
public Number toNumber(StringBuffer value) throws AtlasConversionException {
|
||||
return delegate.toNumber(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(StringBuffer value) {
|
||||
return delegate.toZonedDateTime(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class StringBuilderConverter implements AtlasConverter<StringBuilder> {
|
||||
|
||||
private CharSequenceConverter delegate = new CharSequenceConverter();
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DECIMAL,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigDecimal toBigDecimal(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toBigDecimal(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigInteger toBigInteger(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toBigInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BOOLEAN, concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(StringBuilder value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toBoolean(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.FORMAT, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toByte(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.CHAR, concerns = AtlasConversionConcern.RANGE)
|
||||
public Character toCharacter(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toCharacter(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(StringBuilder date, String sourceFormat, String targetFormat) {
|
||||
return delegate.toDate(date, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DOUBLE, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Double toDouble(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toDouble(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.FLOAT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Float toFloat(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toFloat(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.INTEGER, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Integer toInteger(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(StringBuilder value) {
|
||||
return delegate.toLocalDate(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(StringBuilder value) {
|
||||
return delegate.toLocalTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(StringBuilder value) {
|
||||
return delegate.toLocalDateTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.LONG, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Long toLong(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toLong(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.SHORT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Short toShort(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toShort(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(StringBuilder value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(StringBuilder value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharSequence(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public String toString(StringBuilder value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toString(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(StringBuilder value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(StringBuilder value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuilder(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.NUMBER, concerns = {
|
||||
AtlasConversionConcern.FORMAT })
|
||||
public Number toNumber(StringBuilder value) throws AtlasConversionException {
|
||||
return delegate.toNumber(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(StringBuilder value) {
|
||||
return delegate.toZonedDateTime(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class StringConverter implements AtlasConverter<String> {
|
||||
|
||||
private CharSequenceConverter delegate = new CharSequenceConverter();
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DECIMAL,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigDecimal toBigDecimal(String value) throws AtlasConversionException {
|
||||
return delegate.toBigDecimal(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.FORMAT)
|
||||
public BigInteger toBigInteger(String value) throws AtlasConversionException {
|
||||
return delegate.toBigInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BOOLEAN, concerns = AtlasConversionConcern.CONVENTION)
|
||||
public Boolean toBoolean(String value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toBoolean(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.BYTE, concerns = {
|
||||
AtlasConversionConcern.RANGE, AtlasConversionConcern.FORMAT, AtlasConversionConcern.FRACTIONAL_PART})
|
||||
public Byte toByte(String value) throws AtlasConversionException {
|
||||
return delegate.toByte(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.CHAR, concerns = AtlasConversionConcern.RANGE)
|
||||
public Character toCharacter(String value) throws AtlasConversionException {
|
||||
return delegate.toCharacter(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public Date toDate(String date, String sourceFormat, String targetFormat) {
|
||||
return delegate.toDate(date, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DOUBLE, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Double toDouble(String value) throws AtlasConversionException {
|
||||
return delegate.toDouble(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.FLOAT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE })
|
||||
public Float toFloat(String value) throws AtlasConversionException {
|
||||
return delegate.toFloat(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.INTEGER, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Integer toInteger(String value) throws AtlasConversionException {
|
||||
return delegate.toInteger(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(String value) {
|
||||
return delegate.toLocalDate(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(String value) {
|
||||
return delegate.toLocalTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(String value) {
|
||||
return delegate.toLocalDateTime(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.LONG, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Long toLong(String value) throws AtlasConversionException {
|
||||
return delegate.toLong(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.SHORT, concerns = {
|
||||
AtlasConversionConcern.FORMAT, AtlasConversionConcern.RANGE, AtlasConversionConcern.FRACTIONAL_PART })
|
||||
public Short toShort(String value) throws AtlasConversionException {
|
||||
return delegate.toShort(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(String value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(String value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toCharSequence(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public String toString(String value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toString(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(String value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuffer(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(String value, String sourceFormat, String targetFormat) {
|
||||
return delegate.toStringBuilder(value, sourceFormat, targetFormat);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.NUMBER, concerns = {
|
||||
AtlasConversionConcern.FORMAT })
|
||||
public Number toNumber(String value) throws AtlasConversionException {
|
||||
return delegate.toNumber(value);
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.STRING, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(String value) {
|
||||
return delegate.toZonedDateTime(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class ZonedDateTimeConverter implements AtlasConverter<ZonedDateTime> {
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DECIMAL,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public BigDecimal toBigDecimal(ZonedDateTime value) {
|
||||
return value != null ? BigDecimal.valueOf(getEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.BIG_INTEGER,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public BigInteger toBigInteger(ZonedDateTime value) {
|
||||
return value != null ? BigInteger.valueOf(getEpochMilli(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.BYTE,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.TIMEZONE})
|
||||
public Byte toByte(ZonedDateTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getEpochMilli(value);
|
||||
if (longValue >= Byte.MIN_VALUE && longValue <= Byte.MAX_VALUE) {
|
||||
return longValue.byteValue();
|
||||
}
|
||||
throw new AtlasConversionException(
|
||||
String.format("ZonedDateTime %s is greater than Byte.MAX_VALUE or less than Byte.MIN_VALUE", value));
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME_TZ)
|
||||
public Calendar toCalendar(ZonedDateTime value) {
|
||||
return value != null ? GregorianCalendar.from(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public Date toDate(ZonedDateTime value) {
|
||||
return value != null ? Date.from(value.toInstant()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DOUBLE,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public Double toDouble(ZonedDateTime value) {
|
||||
return value != null ? getEpochMilli(value).doubleValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.FLOAT,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public Float toFloat(ZonedDateTime value) {
|
||||
return value != null ? getEpochMilli(value).floatValue() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME_TZ)
|
||||
public GregorianCalendar toGregorianCalendar(ZonedDateTime value) {
|
||||
return value != null ? GregorianCalendar.from(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.INTEGER,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.TIMEZONE})
|
||||
public Integer toInteger(ZonedDateTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getEpochMilli(value);
|
||||
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
|
||||
throw new AtlasConversionException(String
|
||||
.format("ZonedDateTime %s is greater than Integer.MAX_VALUE or less than Integer.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.intValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE)
|
||||
public LocalDate toLocalDate(ZonedDateTime value) {
|
||||
return value != null ? value.toLocalDate() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME)
|
||||
public LocalDateTime toLocalDateTime(ZonedDateTime value) {
|
||||
return value != null ? value.toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.TIME)
|
||||
public LocalTime toLocalTime(ZonedDateTime value) {
|
||||
return value != null ? value.toLocalTime() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.LONG,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public Long toLong(ZonedDateTime value) {
|
||||
return value != null ? getEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.SHORT,
|
||||
concerns = {AtlasConversionConcern.RANGE, AtlasConversionConcern.TIMEZONE})
|
||||
public Short toShort(ZonedDateTime value) throws AtlasConversionException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Long longValue = getEpochMilli(value);
|
||||
if (longValue > Short.MAX_VALUE || longValue < Short.MIN_VALUE) {
|
||||
throw new AtlasConversionException(
|
||||
String.format("LocalDateTime %s is greater than Short.MAX_VALUE or less than Short.MIN_VALUE", value));
|
||||
}
|
||||
return longValue.shortValue();
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.STRING)
|
||||
public String toString(ZonedDateTime value) {
|
||||
return value != null ? value.toString() : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.STRING)
|
||||
public CharBuffer toCharBuffer(ZonedDateTime value) {
|
||||
return value != null ? CharBuffer.wrap(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.STRING)
|
||||
public CharSequence toCharSequence(ZonedDateTime value) {
|
||||
return value != null ? toString(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.STRING)
|
||||
public StringBuffer toStringBuffer(ZonedDateTime value) {
|
||||
return value != null ? new StringBuffer(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.STRING)
|
||||
public StringBuilder toStringBuilder(ZonedDateTime value) {
|
||||
return value != null ? new StringBuilder(toString(value)) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.NUMBER,
|
||||
concerns = AtlasConversionConcern.TIMEZONE)
|
||||
public Number toNumber(ZonedDateTime value) {
|
||||
return value != null ? getEpochMilli(value) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE)
|
||||
public java.sql.Date toSqlDate(ZonedDateTime value) {
|
||||
return value != null ? java.sql.Date.valueOf(value.toLocalDate()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.TIME)
|
||||
public java.sql.Time toSqlTime(ZonedDateTime value) {
|
||||
return value != null ? java.sql.Time.valueOf(value.toLocalTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME)
|
||||
public java.sql.Timestamp toSqlTimestamp(ZonedDateTime value) {
|
||||
return value != null ? java.sql.Timestamp.valueOf(value.toLocalDateTime()) : null;
|
||||
}
|
||||
|
||||
@AtlasConversionInfo(sourceType = FieldType.DATE_TIME_TZ, targetType = FieldType.DATE_TIME_TZ)
|
||||
public ZonedDateTime toZonedDateTime(ZonedDateTime value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
private Long getEpochMilli(ZonedDateTime value) {
|
||||
return value.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import io.atlasmap.api.AtlasContextFactory;
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.v2.ADMDigest;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.DataSourceKey;
|
||||
import io.atlasmap.v2.DataSourceMetadata;
|
||||
import io.atlasmap.v2.Json;
|
||||
|
||||
/**
|
||||
* <div>
|
||||
* The API for handling ADM archive. It encapsulates ADM archive structure
|
||||
* and format and isolate file/stream I/O from other part.
|
||||
* ADM archive is a zipped archive file or its exploded directory which contains
|
||||
* <ul>
|
||||
* <li>Mapping Definition file (atlasmapping-UI.n.json)</li>
|
||||
* <li>Gzipped digest file which contains all non-Java document metadata
|
||||
* and mapping definition in a single JSON file (adm-catalog-files-n.gz)</li>
|
||||
* <li>Java libraries (jar files in lib/ directory)</li>
|
||||
* </ul>
|
||||
* </div>
|
||||
* {@link #load(Path)} {@link #export(OutputStream)}
|
||||
*
|
||||
* <div>
|
||||
* This handler follows lazy loading strategy as much as
|
||||
* possible, i.e. defer to serialize/deserialize until it is really required.
|
||||
* Also note that at this moment Java library directory is not managed by this class.
|
||||
* Only when it imports/exports ADM archive file, library jars are extracted/bundled
|
||||
* if {@link #isIgnoreLibrary} is set to {@code false}.
|
||||
* </div>
|
||||
*
|
||||
* <div>
|
||||
* TODO <a href="https://github.com/atlasmap/atlasmap/issues/1476">
|
||||
* https://github.com/atlasmap/atlasmap/issues/1476</a>
|
||||
* A gzipped digest file have to be splitted into individual schemas and a catalog file.
|
||||
* </div>
|
||||
*/
|
||||
public class ADMArchiveHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ADMArchiveHandler.class);
|
||||
private static final String MAPPING_DEFINITION_FILTER = "atlasmapping";
|
||||
private static final String MAPPING_DEFINITION_TEMPLATE = "atlasmapping-UI.%s.json";
|
||||
private static final String GZIPPED_ADM_DIGEST_FILTER = "adm-catalog-files";
|
||||
private static final String GZIPPED_ADM_DIGEST_TEMPLATE = "adm-catalog-files-%s.gz";
|
||||
|
||||
private byte[] buffer = new byte[2048];
|
||||
private byte[] gzippedAdmDigestBytes = null;
|
||||
private byte[] mappingDefinitionBytes = null;
|
||||
private ObjectMapper jsonMapper;
|
||||
private ObjectMapper jsonMapperForDigest;
|
||||
|
||||
private AtlasMapping mappingDefinition = null;
|
||||
private String mappingDefinitionId = "0";
|
||||
private Map<DataSourceKey, DataSourceMetadata> dataSourceMetadata;
|
||||
private boolean ignoreLibrary = false;
|
||||
private Path persistDirectory;
|
||||
private Path libraryDirectory;
|
||||
|
||||
public ADMArchiveHandler() {
|
||||
this(ADMArchiveHandler.class.getClassLoader());
|
||||
}
|
||||
|
||||
public ADMArchiveHandler(ClassLoader loader) {
|
||||
this.jsonMapper = Json.withClassLoader(loader);
|
||||
this.jsonMapperForDigest = this.jsonMapper.copy();
|
||||
this.jsonMapperForDigest.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an ADM archive file, an exploded directory or mapping definition JSON file.
|
||||
* @param path {@code java.nio.file.Path} of the ADM archive file or an exploded directory
|
||||
* @throws AtlasException If it fails to load
|
||||
*/
|
||||
public void load(Path path) throws AtlasException {
|
||||
clear();
|
||||
File file = path.toFile();
|
||||
if (!file.exists() || (!file.isFile() && !file.isDirectory())) {
|
||||
throw new AtlasException(
|
||||
String.format("'%s' doesn't exist or is not a regular file/directory", path.toString()));
|
||||
}
|
||||
|
||||
if (file.isDirectory()) {
|
||||
loadExploded(file);
|
||||
} else if (file.getName().toLowerCase().endsWith(".adm")){
|
||||
loadADMFile(file);
|
||||
} else {
|
||||
try (FileInputStream fin = new FileInputStream(file)) {
|
||||
this.mappingDefinitionBytes = readIntoByteArray(fin);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(
|
||||
String.format("Invalid mapping definition file: '%s'", path.toString()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an ADM archive from stream.
|
||||
* @param in InputStream to read an ADM Archive
|
||||
* @throws AtlasException If it fails to load
|
||||
*/
|
||||
public void load(InputStream in) throws AtlasException {
|
||||
load(AtlasContextFactory.Format.ADM, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an ADM archive or mapping definition from stream.
|
||||
* @param format {@code AtlasContextFactory.Format} to indicate stream format
|
||||
* @param in InputStream to read an ADM Archive
|
||||
* @throws AtlasException If it fails to load
|
||||
*/
|
||||
public void load(AtlasContextFactory.Format format, InputStream in) throws AtlasException {
|
||||
if (format == AtlasContextFactory.Format.ADM) {
|
||||
loadADMStream(in);
|
||||
} else {
|
||||
try {
|
||||
this.mappingDefinitionBytes = readIntoByteArray(in);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException("Invalid mapping definition from stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export into an ADM archive.
|
||||
* @param out OutputStream to write an ADM archive
|
||||
* @throws AtlasException If it fails to export
|
||||
*/
|
||||
public void export(OutputStream out) throws AtlasException {
|
||||
LOG.debug("Creating ADM archive file for ID:'{}'", this.mappingDefinitionId);
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(out)) {
|
||||
ZipEntry catEntry = null;
|
||||
|
||||
if (this.getMappingDefinitionBytes() != null) {
|
||||
String mappingFileName = getMappingDefinitionFileName();
|
||||
LOG.debug(" Creating mapping definition file '{}'", mappingFileName);
|
||||
catEntry = new ZipEntry(mappingFileName);
|
||||
zipOut.putNextEntry(catEntry);
|
||||
zipOut.write(getMappingDefinitionBytes(), 0, getMappingDefinitionBytes().length);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
|
||||
if (getGzippedADMDigestBytes() != null) {
|
||||
LOG.debug(" Creating gzipped ADM digest file '{}'", getGzippedADMDigestFileName());
|
||||
catEntry = new ZipEntry(getGzippedADMDigestFileName());
|
||||
zipOut.putNextEntry(catEntry);
|
||||
zipOut.write(getGzippedADMDigestBytes(), 0, getGzippedADMDigestBytes().length);
|
||||
zipOut.closeEntry();
|
||||
|
||||
zipOut.putNextEntry(new ZipEntry("lib/"));
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
|
||||
if (!isIgnoreLibrary() && libraryDirectory != null && libraryDirectory.toFile().isDirectory()) {
|
||||
for (File jarFile : libraryDirectory.toFile().listFiles()) {
|
||||
LOG.debug(" Creating jar file entry '{}'", "lib/" + jarFile.getName());
|
||||
ZipEntry libEntry = new ZipEntry("lib/" + jarFile.getName());
|
||||
zipOut.putNextEntry(libEntry);
|
||||
redirectStream(new FileInputStream(jarFile), zipOut);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException("Error exporting ADM archive file", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist ADM archive into a directory.
|
||||
* @throws AtlasException If it fails to persist
|
||||
*/
|
||||
public void persist() throws AtlasException {
|
||||
if (this.persistDirectory == null) {
|
||||
throw new AtlasException("Persist Directory must be set");
|
||||
}
|
||||
|
||||
Path mdPath = this.persistDirectory.resolve(getMappingDefinitionFileName());
|
||||
if (getMappingDefinitionBytes() != null) {
|
||||
try {
|
||||
this.mappingDefinition = jsonMapper.readValue(getMappingDefinitionBytes(), AtlasMapping.class);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Invalid serialized mapping definition content detected, discarding");
|
||||
if (LOG.isDebugEnabled()) {
|
||||
String str = String.format("Mapping Definition: [%s]: ",
|
||||
getMappingDefinitionBytes() != null ? new String(getMappingDefinitionBytes()) : "");
|
||||
LOG.warn(str, e);
|
||||
}
|
||||
this.mappingDefinitionBytes = null;
|
||||
this.mappingDefinition = null;
|
||||
}
|
||||
}
|
||||
if (this.mappingDefinition != null) {
|
||||
try {
|
||||
jsonMapper.writeValue(mdPath.toFile(), this.mappingDefinition);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to persist mapping definition", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (getGzippedADMDigestBytes() != null) {
|
||||
Path digestPath = this.persistDirectory.resolve(getGzippedADMDigestFileName());
|
||||
try (FileOutputStream out = new FileOutputStream(digestPath.toFile())) {
|
||||
out.write(getGzippedADMDigestBytes());
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to persist gzipped ADM digest file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AtlasMapping getMappingDefinition() {
|
||||
if (this.mappingDefinition == null && this.mappingDefinitionBytes != null) {
|
||||
try {
|
||||
this.mappingDefinition = jsonMapper.readValue(this.mappingDefinitionBytes,
|
||||
AtlasMapping.class);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Invalid serialized mapping definition content detected, discarding");
|
||||
this.mappingDefinitionBytes = null;
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.warn("", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.mappingDefinition;
|
||||
}
|
||||
|
||||
public void setMappingDefinition(AtlasMapping mapping) {
|
||||
this.mappingDefinitionBytes = null;
|
||||
this.mappingDefinition = mapping;
|
||||
}
|
||||
|
||||
public void setMappingDefinitionBytes(InputStream is) throws AtlasException {
|
||||
try {
|
||||
this.mappingDefinition = null;
|
||||
this.mappingDefinitionBytes = readIntoByteArray(is);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(this.jsonMapper.writeValueAsString(getMappingDefinition()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getMappingDefinitionBytes() throws AtlasException {
|
||||
try {
|
||||
if (this.mappingDefinitionBytes == null && this.mappingDefinition != null) {
|
||||
this.mappingDefinitionBytes = jsonMapper.writeValueAsBytes(this.mappingDefinition);
|
||||
}
|
||||
return this.mappingDefinitionBytes;
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setGzippedADMDigest(InputStream is) throws AtlasException {
|
||||
try {
|
||||
this.gzippedAdmDigestBytes = readIntoByteArray(is);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getGzippedADMDigestBytes() {
|
||||
return this.gzippedAdmDigestBytes;
|
||||
}
|
||||
|
||||
public DataSourceMetadata getDataSourceMetadata(boolean isSource, String documentId) throws AtlasException {
|
||||
return getDataSourceMetadata(new DataSourceKey(isSource, documentId));
|
||||
}
|
||||
|
||||
public DataSourceMetadata getDataSourceMetadata(DataSourceKey key) throws AtlasException {
|
||||
if (getDataSourceMetadataMap() == null) {
|
||||
return null;
|
||||
}
|
||||
return getDataSourceMetadataMap().get(key);
|
||||
}
|
||||
|
||||
public Map<DataSourceKey, DataSourceMetadata> getDataSourceMetadataMap() throws AtlasException {
|
||||
if (this.dataSourceMetadata == null) {
|
||||
if (this.gzippedAdmDigestBytes == null) {
|
||||
return null;
|
||||
}
|
||||
try (GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(this.gzippedAdmDigestBytes))) {
|
||||
ADMDigest digest = jsonMapperForDigest.readValue(in, ADMDigest.class);
|
||||
this.dataSourceMetadata = new HashMap<>();
|
||||
for (int i=0; i<digest.getExportMeta().length; i++) {
|
||||
DataSourceMetadata meta = digest.getExportMeta()[i];
|
||||
String spec = digest.getExportBlockData()[i].getValue();
|
||||
if (meta.getId() == null) {
|
||||
meta.setId(meta.getName());
|
||||
}
|
||||
meta.setSpecification(spec != null ? spec.getBytes() : null);
|
||||
this.dataSourceMetadata.put(new DataSourceKey(meta.getIsSource(), meta.getId()), meta);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(this.dataSourceMetadata);
|
||||
}
|
||||
|
||||
public AtlasMapping cloneMappingDefinition() throws AtlasException {
|
||||
AtlasMapping atlasMapping = getMappingDefinition();
|
||||
if (atlasMapping == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
byte[] bytes = this.jsonMapper.writeValueAsBytes(atlasMapping);
|
||||
return this.jsonMapper.readValue(bytes, AtlasMapping.class);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.mappingDefinitionBytes = null;
|
||||
this.mappingDefinition = null;
|
||||
this.gzippedAdmDigestBytes = null;
|
||||
this.dataSourceMetadata = null;
|
||||
}
|
||||
|
||||
public void setIgnoreLibrary(boolean ignoreLib) {
|
||||
this.ignoreLibrary = ignoreLib;
|
||||
}
|
||||
|
||||
public boolean isIgnoreLibrary() {
|
||||
return this.ignoreLibrary;
|
||||
}
|
||||
|
||||
public void setPersistDirectory(Path dir) throws AtlasException {
|
||||
ensureDirectory(dir);
|
||||
this.persistDirectory = dir;
|
||||
}
|
||||
|
||||
public void setLibraryDirectory(Path dir) throws AtlasException {
|
||||
ensureDirectory(dir);
|
||||
this.libraryDirectory = dir;
|
||||
}
|
||||
|
||||
public void setMappingDefinitionId(String id) {
|
||||
this.mappingDefinitionId = id;
|
||||
}
|
||||
|
||||
public String getGzippedADMDigestFileName() {
|
||||
return String.format(GZIPPED_ADM_DIGEST_TEMPLATE, this.mappingDefinitionId);
|
||||
}
|
||||
|
||||
public String getMappingDefinitionFileName() {
|
||||
return String.format(MAPPING_DEFINITION_TEMPLATE, this.mappingDefinitionId);
|
||||
}
|
||||
|
||||
private void loadExploded(File dir) throws AtlasException {
|
||||
setPersistDirectory(dir.toPath());
|
||||
this.mappingDefinitionId = dir.getName();
|
||||
File mappingDefinitionFile = dir.toPath().resolve(getMappingDefinitionFileName()).toFile();
|
||||
if (mappingDefinitionFile.exists() && mappingDefinitionFile.isFile()) {
|
||||
try (InputStream mappingdefis = new FileInputStream(mappingDefinitionFile)) {
|
||||
this.mappingDefinitionBytes = readIntoByteArray(mappingdefis);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException("Failed to read mapping definition file", e);
|
||||
}
|
||||
}
|
||||
|
||||
File digestFile = dir.toPath().resolve(getGzippedADMDigestFileName()).toFile();
|
||||
if (digestFile.exists() && digestFile.isFile()) {
|
||||
try (InputStream digestis = new FileInputStream(digestFile)) {
|
||||
this.gzippedAdmDigestBytes = readIntoByteArray(digestis);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException("Failed to read digest file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadADMFile(File file) throws AtlasException {
|
||||
try {
|
||||
loadADMStream(new FileInputStream(file));
|
||||
} catch (AtlasException ae) {
|
||||
throw ae;
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadADMStream(InputStream in) throws AtlasException {
|
||||
String catEntryName;
|
||||
ZipEntry catEntry;
|
||||
ZipInputStream zipIn = null;
|
||||
try {
|
||||
zipIn = new ZipInputStream(in);
|
||||
boolean mappingDefinitionFound = false;
|
||||
while ((catEntry = zipIn.getNextEntry()) != null) {
|
||||
catEntryName = catEntry.getName();
|
||||
LOG.debug(" Extracting ADM file entry '{}'", catEntryName);
|
||||
if (catEntryName.contains(GZIPPED_ADM_DIGEST_FILTER)) {
|
||||
this.gzippedAdmDigestBytes = readIntoByteArray(zipIn);
|
||||
} else if (!isIgnoreLibrary() && catEntryName.contains(".jar")) {
|
||||
if (this.libraryDirectory == null) {
|
||||
throw new AtlasException("Library directory is not specified");
|
||||
}
|
||||
int separatorPos = catEntryName.replaceAll("\\\\", "/").lastIndexOf("/");
|
||||
String name = separatorPos == -1 ? catEntryName : catEntryName.substring(separatorPos + 1);
|
||||
Path libPath = this.libraryDirectory.resolve(name);
|
||||
try (FileOutputStream fos = new FileOutputStream(libPath.toFile())) {
|
||||
redirectStream(zipIn, fos);
|
||||
} catch (Exception e) {
|
||||
LOG.warn(String.format("Failed to save a jar file '%s', ignoring...", name), e);
|
||||
}
|
||||
} else if (catEntryName.contains(MAPPING_DEFINITION_FILTER)) {
|
||||
if (mappingDefinitionFound) {
|
||||
throw new AtlasException("Multiple mapping definition files are found in a same .adm archive");
|
||||
}
|
||||
this.mappingDefinitionBytes = readIntoByteArray(zipIn);
|
||||
mappingDefinitionFound = true;
|
||||
} else {
|
||||
LOG.debug("Ignoring file '{}' in .adm archive", catEntryName);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
} finally {
|
||||
try {
|
||||
zipIn.close();
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void redirectStream(InputStream in, OutputStream out) throws Exception {
|
||||
int len = 0;
|
||||
while ((len = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] readIntoByteArray(InputStream in) throws Exception {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
redirectStream(in, baos);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ensureDirectory(Path dir) throws AtlasException {
|
||||
if (dir == null) {
|
||||
throw new AtlasException(String.format("Directory must not be Null"));
|
||||
}
|
||||
File dirf = dir.toFile();
|
||||
if (dirf.exists() && !dirf.isDirectory()) {
|
||||
throw new AtlasException(String.format("File '%s' is not a directory", dirf.getAbsolutePath()));
|
||||
} else if (!dirf.exists()) {
|
||||
dirf.mkdirs();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,559 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.v2.AtlasModelFactory;
|
||||
import io.atlasmap.v2.CollectionType;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
|
||||
public class AtlasPath implements Cloneable {
|
||||
|
||||
public static final String PATH_SEPARATOR = "/";
|
||||
public static final char PATH_SEPARATOR_CHAR = '/';
|
||||
public static final String PATH_SEPARATOR_ESCAPED = "/";
|
||||
public static final String PATH_ARRAY_START = "[";
|
||||
public static final String PATH_ARRAY_END = "]";
|
||||
public static final String PATH_ARRAY_SUFFIX = PATH_ARRAY_START + PATH_ARRAY_END;
|
||||
public static final String PATH_LIST_START = "<";
|
||||
public static final String PATH_LIST_END = ">";
|
||||
public static final String PATH_LIST_SUFFIX = PATH_LIST_START + PATH_LIST_END;
|
||||
public static final String PATH_MAP_START = "{";
|
||||
public static final String PATH_MAP_END = "}";
|
||||
public static final String PATH_MAP_SUFFIX = PATH_MAP_START + PATH_MAP_END;
|
||||
public static final String PATH_ATTRIBUTE_PREFIX = "@";
|
||||
public static final String PATH_NAMESPACE_SEPARATOR = ":";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasPath.class);
|
||||
|
||||
protected List<SegmentContext> segmentContexts;
|
||||
private String originalPath = null;
|
||||
|
||||
public AtlasPath(String p) {
|
||||
String path = p;
|
||||
this.originalPath = path;
|
||||
this.segmentContexts = parse(path);
|
||||
}
|
||||
|
||||
protected AtlasPath(List<SegmentContext> segments) {
|
||||
this.segmentContexts = segments;
|
||||
this.originalPath = getSegmentPath(segments.get(segments.size() - 1));
|
||||
}
|
||||
|
||||
private AtlasPath() {
|
||||
this.segmentContexts = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract child fields by feeding relative path.
|
||||
*
|
||||
* @param f Parent field to extract from
|
||||
* @param path Relative path string
|
||||
* @return extracted field(s)
|
||||
*/
|
||||
public static Field extractChildren(Field f, String path) {
|
||||
if (f == null || path == null || path.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (path.equals(PATH_SEPARATOR)) {
|
||||
return f;
|
||||
}
|
||||
if (!(f instanceof FieldGroup)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Field> extracted = new ArrayList<>();
|
||||
FieldGroup entryField = (FieldGroup)f;
|
||||
extracted.add(entryField);
|
||||
List<SegmentContext> entrySegments = new AtlasPath(entryField.getPath()).getSegments(true);
|
||||
SegmentContext entrySegment = entrySegments.get(entrySegments.size() - 1);
|
||||
List<SegmentContext> extractedSegments = new ArrayList<>(entrySegments);
|
||||
List<SegmentContext> relativeSegments = new AtlasPath(path).getSegments(true);
|
||||
SegmentContext relativeRootSegment = relativeSegments.get(0);
|
||||
|
||||
List<Field> selected = new ArrayList<>();
|
||||
if (relativeRootSegment.getCollectionType() == null || relativeRootSegment.getCollectionType() == CollectionType.NONE) {
|
||||
if (entrySegment.getCollectionType() != null
|
||||
&& entrySegment.getCollectionType() != CollectionType.NONE
|
||||
&& entrySegment.getCollectionIndex() == null) {
|
||||
selected.addAll(entryField.getField());
|
||||
} else {
|
||||
selected.add(entryField);
|
||||
}
|
||||
} else if (relativeRootSegment.getCollectionIndex() != null) {
|
||||
if (entrySegment.getCollectionIndex() != null) {
|
||||
if (entrySegment.getCollectionIndex() == relativeRootSegment.getCollectionIndex()) {
|
||||
selected.add(entryField);
|
||||
}
|
||||
} else {
|
||||
selected.add(entryField.getField().get(relativeRootSegment.getCollectionIndex()));
|
||||
entrySegment.collectionIndex = relativeRootSegment.getCollectionIndex();
|
||||
extractedSegments.set(entrySegments.size() - 1, entrySegment.rebuild());
|
||||
}
|
||||
} else {
|
||||
selected.addAll(entryField.getField());
|
||||
}
|
||||
extracted = selected;
|
||||
|
||||
for (int i=1; i<relativeSegments.size(); i++) {
|
||||
SegmentContext segment = relativeSegments.get(i);
|
||||
extractedSegments.add(segment);
|
||||
selected = new ArrayList<>();
|
||||
|
||||
for (Field f1 : extracted) {
|
||||
FieldGroup f1Group = (FieldGroup)f1;
|
||||
for (Field f2 : f1Group.getField()) {
|
||||
AtlasPath f2Path = new AtlasPath(f2.getPath());
|
||||
if (!segment.getName().equals(f2Path.getLastSegment().getName())) {
|
||||
continue;
|
||||
}
|
||||
if (segment.getCollectionType() == CollectionType.NONE) {
|
||||
selected.add(f2);
|
||||
} else {
|
||||
FieldGroup f2Group = (FieldGroup)f2;
|
||||
if (segment.getCollectionIndex() != null) {
|
||||
selected.add((f2Group.getField().get(segment.getCollectionIndex())));
|
||||
} else {
|
||||
selected.addAll(f2Group.getField());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
extracted = selected;
|
||||
}
|
||||
|
||||
if (extracted.size() == 1) {
|
||||
return extracted.get(0);
|
||||
}
|
||||
FieldGroup answer = AtlasModelFactory.createFieldGroupFrom(f, true);
|
||||
answer.setPath(new AtlasPath(extractedSegments).toString());
|
||||
answer.getField().addAll(extracted);
|
||||
return answer;
|
||||
}
|
||||
|
||||
public static void setCollectionIndexRecursively(FieldGroup group, int segmentIndex, int index) {
|
||||
AtlasPath path = new AtlasPath(group.getPath());
|
||||
path.setCollectionIndex(segmentIndex, index);
|
||||
group.setPath(path.toString());
|
||||
for (Field f : group.getField()) {
|
||||
if (f instanceof FieldGroup) {
|
||||
setCollectionIndexRecursively((FieldGroup)f, segmentIndex, index);
|
||||
} else {
|
||||
AtlasPath fpath = new AtlasPath(f.getPath());
|
||||
fpath.setCollectionIndex(segmentIndex, index);
|
||||
f.setPath(fpath.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AtlasPath appendField(String fieldExpression) {
|
||||
this.segmentContexts.add(createSegmentContext(fieldExpression));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasPath clone() {
|
||||
return new AtlasPath(this.toString());
|
||||
}
|
||||
|
||||
public List<SegmentContext> getSegments(boolean includeRoot) {
|
||||
if (includeRoot) {
|
||||
return Collections.unmodifiableList(this.segmentContexts);
|
||||
}
|
||||
if (this.segmentContexts.size() > 1) {
|
||||
return Collections.unmodifiableList(this.segmentContexts.subList(1, this.segmentContexts.size()));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public Boolean isRoot() {
|
||||
return this.segmentContexts.size() == 1 && this.segmentContexts.get(0).isRoot();
|
||||
}
|
||||
|
||||
public SegmentContext getRootSegment() {
|
||||
return this.segmentContexts.get(0);
|
||||
}
|
||||
|
||||
public Boolean isCollectionRoot() {
|
||||
return this.segmentContexts.size() == 1 && this.segmentContexts.get(0).getCollectionType() != CollectionType.NONE;
|
||||
}
|
||||
|
||||
public Boolean hasCollectionRoot() {
|
||||
return this.segmentContexts.get(0).getCollectionType() != CollectionType.NONE;
|
||||
}
|
||||
|
||||
public SegmentContext getLastSegment() {
|
||||
return this.segmentContexts.get(this.segmentContexts.size()-1);
|
||||
}
|
||||
|
||||
public SegmentContext getLastCollectionSegment() {
|
||||
List<SegmentContext> collectionSegments = getCollectionSegments(true);
|
||||
return collectionSegments.get(collectionSegments.size() - 1);
|
||||
}
|
||||
|
||||
public SegmentContext getLastSegmentParent() {
|
||||
if (this.segmentContexts.isEmpty() || this.segmentContexts.size() == 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.segmentContexts.get(this.segmentContexts.size() - 2);
|
||||
}
|
||||
|
||||
public AtlasPath getLastSegmentParentPath() {
|
||||
if (this.segmentContexts.isEmpty() || this.segmentContexts.size() == 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AtlasPath parentPath = new AtlasPath();
|
||||
for (int i = 0; i < this.segmentContexts.size() - 1; i++) {
|
||||
parentPath.appendField(this.segmentContexts.get(i).getExpression());
|
||||
}
|
||||
return parentPath;
|
||||
}
|
||||
|
||||
public SegmentContext getParentSegmentOf(SegmentContext sc) {
|
||||
for (int i=0; i<this.segmentContexts.size(); i++) {
|
||||
if (this.segmentContexts.get(i) == sc) {
|
||||
if (sc.isRoot()) {
|
||||
return null;
|
||||
}
|
||||
return this.segmentContexts.get(i-1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasCollection() {
|
||||
for (SegmentContext sc : this.segmentContexts) {
|
||||
if (sc.getCollectionType() != CollectionType.NONE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isIndexedCollection() {
|
||||
boolean hasIndexedCollection = false;
|
||||
for (SegmentContext sc : this.segmentContexts) {
|
||||
if (sc.getCollectionType() != CollectionType.NONE) {
|
||||
if (sc.getCollectionIndex() != null) {
|
||||
hasIndexedCollection = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return hasIndexedCollection;
|
||||
}
|
||||
|
||||
public SegmentContext setCollectionIndex(int segmentIndex, Integer collectionIndex) {
|
||||
if (collectionIndex != null && collectionIndex < 0) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Cannnot set negative collection index %s for the path %s",
|
||||
collectionIndex, this.toString()));
|
||||
}
|
||||
SegmentContext sc = this.segmentContexts.get(segmentIndex);
|
||||
sc.collectionIndex = collectionIndex;
|
||||
return this.segmentContexts.set(segmentIndex, sc.rebuild());
|
||||
}
|
||||
|
||||
public List<SegmentContext> getCollectionSegments(boolean includeRoot) {
|
||||
List<SegmentContext> segments = getSegments(includeRoot);
|
||||
List<SegmentContext> collectionSegments = new ArrayList<>();
|
||||
for (SegmentContext segment: segments) {
|
||||
if (segment.getCollectionType() != CollectionType.NONE) {
|
||||
collectionSegments.add(segment);
|
||||
}
|
||||
}
|
||||
return collectionSegments;
|
||||
}
|
||||
|
||||
public SegmentContext setVacantCollectionIndex(Integer collectionIndex) {
|
||||
for (int i = 0; i < this.segmentContexts.size(); i++) {
|
||||
SegmentContext sc = segmentContexts.get(i);
|
||||
if (sc.getCollectionType() != CollectionType.NONE && sc.getCollectionIndex() == null) {
|
||||
return setCollectionIndex(i, collectionIndex);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No Vacant index on collection segments in the path " + this.toString());
|
||||
}
|
||||
|
||||
public String getSegmentPath(SegmentContext sc) {
|
||||
int toIndex = this.segmentContexts.indexOf(sc);
|
||||
if (toIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder().append(PATH_SEPARATOR_CHAR);
|
||||
if (!this.segmentContexts.get(0).getExpression().isEmpty()) {
|
||||
builder.append(this.segmentContexts.get(0).getExpression());
|
||||
}
|
||||
for (int i=1; i<=toIndex; i++) {
|
||||
if (!(builder.charAt(builder.length()-1) == PATH_SEPARATOR_CHAR)) {
|
||||
builder.append(PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
builder.append(this.segmentContexts.get(i).getExpression());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSegmentPath(getLastSegment());
|
||||
}
|
||||
|
||||
public String getOriginalPath() {
|
||||
return originalPath;
|
||||
}
|
||||
|
||||
public int getCollectionSegmentCount() {
|
||||
int answer = 0;
|
||||
for (SegmentContext sc : getSegments(true)) {
|
||||
if (sc.collectionType != null && sc.collectionType != CollectionType.NONE) {
|
||||
answer++;
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected List<SegmentContext> parse(String path) {
|
||||
path = sanitize(path);
|
||||
List<SegmentContext> segmentContexts = new ArrayList<>();
|
||||
if (path != null && !"".equals(path)) {
|
||||
if (path.startsWith(PATH_SEPARATOR)) {
|
||||
path = path.replaceFirst(PATH_SEPARATOR, "");
|
||||
}
|
||||
if (path.contains(PATH_SEPARATOR)) {
|
||||
String[] parts = path.split(PATH_SEPARATOR_ESCAPED, 512);
|
||||
for (String part : parts) {
|
||||
segmentContexts.add(createSegmentContext(part));
|
||||
}
|
||||
} else {
|
||||
segmentContexts.add(createSegmentContext(path));
|
||||
}
|
||||
}
|
||||
if (segmentContexts.isEmpty() || !segmentContexts.get(0).isRoot()) {
|
||||
// add root segment if there's not
|
||||
segmentContexts.add(0, createSegmentContext(""));
|
||||
}
|
||||
return segmentContexts;
|
||||
}
|
||||
|
||||
protected String sanitize(String path) {
|
||||
String answer = path;
|
||||
if (answer == null || answer.isEmpty()) {
|
||||
return answer;
|
||||
}
|
||||
if (answer.indexOf("//") != -1) {
|
||||
LOG.warn("Sanitizing double slash (//) in the path '{}'", answer);
|
||||
answer = answer.replaceAll("//", "/");
|
||||
}
|
||||
if (answer.endsWith("/")) {
|
||||
LOG.warn("Sanitizing trailing slash (/) in the path '{}'", answer);
|
||||
answer = answer.substring(0, answer.length()-1);
|
||||
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected SegmentContext createSegmentContext(String expression) {
|
||||
return new SegmentContext(expression);
|
||||
}
|
||||
|
||||
public static class SegmentContext {
|
||||
|
||||
private String name;
|
||||
private String expression;
|
||||
private CollectionType collectionType;
|
||||
private Integer collectionIndex;
|
||||
private String mapKey;
|
||||
private boolean isAttribute;
|
||||
private boolean isRoot;
|
||||
|
||||
public SegmentContext(String expression) {
|
||||
this.expression = expression;
|
||||
if (this.expression.startsWith(PATH_SEPARATOR)) {
|
||||
this.expression = this.expression.replaceFirst(PATH_SEPARATOR, "");
|
||||
}
|
||||
this.name = cleanPathSegment(expression);
|
||||
if (expression.contains(PATH_MAP_START)) {
|
||||
this.collectionType = CollectionType.MAP;
|
||||
} else if (expression.contains(PATH_ARRAY_START)) {
|
||||
this.collectionType = CollectionType.ARRAY;
|
||||
} else if (expression.contains(PATH_LIST_START)) {
|
||||
this.collectionType = CollectionType.LIST;
|
||||
} else {
|
||||
this.collectionType = CollectionType.NONE;
|
||||
}
|
||||
if (this.collectionType == CollectionType.MAP) {
|
||||
this.mapKey = getMapKey(expression);
|
||||
} else {
|
||||
this.collectionIndex = getCollectionIndex(expression);
|
||||
}
|
||||
this.isAttribute = expression.startsWith(PATH_ATTRIBUTE_PREFIX);
|
||||
this.isRoot = this.name.isEmpty();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public CollectionType getCollectionType() {
|
||||
return this.collectionType;
|
||||
}
|
||||
|
||||
public Integer getCollectionIndex() {
|
||||
return this.collectionIndex;
|
||||
}
|
||||
|
||||
public String getMapKey() {
|
||||
return this.mapKey;
|
||||
}
|
||||
|
||||
public boolean isAttribute() {
|
||||
return isAttribute;
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
return isRoot;
|
||||
}
|
||||
|
||||
protected SegmentContext rebuild() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (this.isAttribute) {
|
||||
buf.append(PATH_ATTRIBUTE_PREFIX);
|
||||
}
|
||||
buf.append(name);
|
||||
String index = collectionIndex != null ? collectionIndex.toString() : "";
|
||||
if (this.collectionType == CollectionType.ARRAY) {
|
||||
buf.append(PATH_ARRAY_START).append(index).append(PATH_ARRAY_END);
|
||||
} else if (this.collectionType == CollectionType.LIST) {
|
||||
buf.append(PATH_LIST_START).append(index).append(PATH_LIST_END);
|
||||
} else if (this.collectionType == CollectionType.MAP) {
|
||||
buf.append(PATH_LIST_START).append(mapKey).append(PATH_LIST_END);
|
||||
}
|
||||
return new SegmentContext(buf.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return collectionType == CollectionType.MAP
|
||||
? String.format("SegmentContext [name=%s, expression=%s, collectionType=%s, mapKey=%s]",
|
||||
name, expression, collectionType, mapKey)
|
||||
: String.format(
|
||||
"SegmentContext [name=%s, expression=%s, collectionType=%s, collectionIndex=%s]",
|
||||
name, expression, collectionType, collectionIndex);
|
||||
}
|
||||
|
||||
protected String cleanPathSegment(String expression) {
|
||||
String answer = expression;
|
||||
if (answer == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// strip namespace if there is one
|
||||
if (answer.contains(PATH_NAMESPACE_SEPARATOR)) {
|
||||
answer = answer.substring(answer.indexOf(PATH_NAMESPACE_SEPARATOR) + 1);
|
||||
}
|
||||
|
||||
if (answer.contains(PATH_ARRAY_START) && answer.endsWith(PATH_ARRAY_END)) {
|
||||
return answer.substring(0, answer.indexOf(PATH_ARRAY_START, 0));
|
||||
}
|
||||
|
||||
if (answer.contains(PATH_LIST_START) && answer.endsWith(PATH_LIST_END)) {
|
||||
return answer.substring(0, answer.indexOf(PATH_LIST_START, 0));
|
||||
}
|
||||
|
||||
if (answer.contains(PATH_MAP_START) && answer.endsWith(PATH_MAP_END)) {
|
||||
return answer.substring(0, answer.indexOf(PATH_MAP_START, 0));
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
private Integer getCollectionIndex(String expression) {
|
||||
if (expression == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expression.contains(PATH_ARRAY_START) && expression.endsWith(PATH_ARRAY_END)) {
|
||||
int start = expression.indexOf(PATH_ARRAY_START, 0) + 1;
|
||||
String index = expression.substring(start, expression.indexOf(PATH_ARRAY_END, start));
|
||||
if (index != null && index.length() > 0) {
|
||||
return Integer.valueOf(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expression.contains(PATH_LIST_START) && expression.endsWith(PATH_LIST_END)) {
|
||||
int start = expression.indexOf(PATH_LIST_START, 0) + 1;
|
||||
String index = expression.substring(start, expression.indexOf(PATH_LIST_END, start));
|
||||
if (index != null && index.length() > 0) {
|
||||
return Integer.valueOf(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getMapKey(String expression) {
|
||||
int start = expression.indexOf(PATH_MAP_START, 0) + 1;
|
||||
String key = expression.substring(start, expression.indexOf(PATH_MAP_END, start));
|
||||
if (key != null && key.length() > 0) {
|
||||
return key;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasSession;
|
||||
import io.atlasmap.spi.AtlasInternalSession;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.v2.Audit;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.Validation;
|
||||
import io.atlasmap.v2.ValidationStatus;
|
||||
|
||||
public class AtlasUtil {
|
||||
public static final int SPLIT_LIMIT = 4;
|
||||
public static final String NEW_LINE_CHARS = "(?m)$^|[\\r\\n]+\\z";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasUtil.class);
|
||||
|
||||
public static Properties loadPropertiesFromURL(URL url) throws Exception {
|
||||
try (InputStream is = url.openStream()) {
|
||||
Properties prop = new Properties();
|
||||
prop.load(is);
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String string) {
|
||||
return string == null || string.isEmpty() || string.matches("^\\s+$");
|
||||
}
|
||||
|
||||
public static boolean matchUriModule(String uriA, String uriB) {
|
||||
if (uriA == null || uriB == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getUriModule(uriA) == null || getUriModule(uriB) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getUriModule(uriA).equalsIgnoreCase(getUriModule(uriB));
|
||||
|
||||
}
|
||||
|
||||
protected static void validateUri(String atlasUri) {
|
||||
if (!atlasUri.startsWith("atlas:")) {
|
||||
throw new IllegalStateException(
|
||||
"Invalid atlas uri " + atlasUri + " does not begin with 'atlas:': " + atlasUri);
|
||||
}
|
||||
|
||||
if (countCharacters(atlasUri, '?') > 1) {
|
||||
throw new IllegalStateException("Invalid atlas uri " + atlasUri + " multiple '?' characters: " + atlasUri);
|
||||
}
|
||||
}
|
||||
|
||||
protected static List<String> getUriPartsAsArray(String atlasUri) {
|
||||
|
||||
if (atlasUri == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (AtlasUtil.isEmpty(atlasUri)) {
|
||||
return Arrays.asList(new String[0]);
|
||||
}
|
||||
|
||||
validateUri(atlasUri);
|
||||
|
||||
String[] pass1 = null;
|
||||
if (atlasUri.contains("?")) {
|
||||
pass1 = atlasUri.split("\\?", 2);
|
||||
}
|
||||
|
||||
List<String> parts = new ArrayList<String>();
|
||||
if (pass1 != null && pass1.length >= 1) {
|
||||
parts.addAll(Arrays.asList(pass1[0].split(":", 4)));
|
||||
} else {
|
||||
parts.addAll(Arrays.asList(atlasUri.split(":", 4)));
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "scheme" piece of an Atlas uri
|
||||
*
|
||||
* ie. atlas:stringseparated:csv?quoteChar="
|
||||
*
|
||||
*
|
||||
* scheme: atlas module: stringseparated remaining: csv config: quoteChar="
|
||||
*
|
||||
* if atlasUri is null, returns null. if empty or no scheme present, returns
|
||||
* empty. otherwise, the $scheme is returned
|
||||
*
|
||||
*@param atlasUri URI string
|
||||
* @return URI scheme
|
||||
*
|
||||
*/
|
||||
public static String getUriScheme(String atlasUri) {
|
||||
List<String> uriA = AtlasUtil.getUriPartsAsArray(atlasUri);
|
||||
if (uriA == null || uriA.size() < 1 || isEmpty(uriA.get(0))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return uriA.get(0);
|
||||
}
|
||||
|
||||
public static String getUriModule(String atlasUri) {
|
||||
List<String> uriA = AtlasUtil.getUriPartsAsArray(atlasUri);
|
||||
if (uriA == null || uriA.size() < 2 || isEmpty(uriA.get(1))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return uriA.get(1);
|
||||
}
|
||||
|
||||
public static String getUriDataType(String atlasUri) {
|
||||
List<String> uriA = AtlasUtil.getUriPartsAsArray(atlasUri);
|
||||
if (uriA == null || uriA.size() < 3 || isEmpty(uriA.get(2))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return uriA.get(2);
|
||||
}
|
||||
|
||||
public static String getUriModuleVersion(String atlasUri) {
|
||||
List<String> uriA = AtlasUtil.getUriPartsAsArray(atlasUri);
|
||||
if (uriA == null || uriA.size() < 4 || isEmpty(uriA.get(3))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return uriA.get(3);
|
||||
}
|
||||
|
||||
public static String getUriParameterValue(String atlasUri, String key) {
|
||||
Map<String, String> params = getUriParameters(atlasUri);
|
||||
if (params == null || params.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return params.get(key);
|
||||
}
|
||||
|
||||
public static Map<String, String> getUriParameters(String atlasUri) {
|
||||
|
||||
if (atlasUri == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
if (AtlasUtil.isEmpty(atlasUri)) {
|
||||
return params;
|
||||
}
|
||||
|
||||
validateUri(atlasUri);
|
||||
|
||||
String[] pass1 = null;
|
||||
if (atlasUri.contains("?")) {
|
||||
pass1 = atlasUri.split("\\?", 2);
|
||||
}
|
||||
|
||||
if (pass1 == null || pass1.length < 2 || pass1[1] == null || pass1[1].length() < 1) {
|
||||
return params;
|
||||
}
|
||||
|
||||
String allParams = null;
|
||||
try {
|
||||
allParams = URLDecoder.decode(pass1[1], "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LOG.error("Unable to parse uri" + atlasUri + " for configuration parameters", e);
|
||||
return params;
|
||||
}
|
||||
|
||||
if (allParams == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] configs = allParams.split("&", SPLIT_LIMIT);
|
||||
if (configs == null || configs.length < 1) {
|
||||
return params;
|
||||
}
|
||||
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
if (!configs[i].contains("=")) {
|
||||
LOG.warn("Invalid configuration parameter: " + configs[i] + " for uri: '" + atlasUri + "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] cfgs = configs[i].split("=");
|
||||
if (cfgs == null || cfgs.length != 2) {
|
||||
LOG.warn("Invalid configuration parameter: " + configs[i] + " for uri: '" + atlasUri + "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
params.put(cfgs[0], cfgs[1]);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
public static int countCharacters(String text, char match) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
if (text.charAt(i) == match) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static List<Class<?>> findClassesForPackage(String scannedPackage) {
|
||||
String scannedPath = scannedPackage.replace('.', '/');
|
||||
URL scannedUrl = getResource(scannedPath);
|
||||
|
||||
if (scannedUrl == null) {
|
||||
throw new IllegalArgumentException(String.format("Unable to detect resources for url='%s' for package='%s'",
|
||||
scannedPath, scannedPackage));
|
||||
}
|
||||
|
||||
if ("jar".equals(scannedUrl.getProtocol())) {
|
||||
return findClassesFromJar(scannedUrl);
|
||||
}
|
||||
|
||||
File scannedFd = new File(scannedUrl.getFile());
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
|
||||
if (scannedFd.listFiles() == null) {
|
||||
return classes;
|
||||
}
|
||||
|
||||
for (File file : scannedFd.listFiles()) {
|
||||
classes.addAll(find(file, scannedPackage));
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
public static void addAudit(AtlasInternalSession session, Field field,
|
||||
String message, AuditStatus status, String value) {
|
||||
String docId = field != null ? field.getDocId() : null;
|
||||
String docName = session != null ? getDocumentNameById(session, docId) : null;
|
||||
String path = field != null ? field.getPath() : null;
|
||||
session.getAudits().getAudit().add(
|
||||
createAudit(status, docId, docName, path, value, message));
|
||||
}
|
||||
|
||||
public static void addAudit(AtlasInternalSession session, String docId,
|
||||
String message, AuditStatus status, String value) {
|
||||
String docName = session != null ? getDocumentNameById(session, docId) : null;
|
||||
session.getAudits().getAudit().add(
|
||||
createAudit(status, docId, docName, null, value, message));
|
||||
}
|
||||
|
||||
public static Audit createAudit(AuditStatus status, String docId, String docName,
|
||||
String path, String value, String message) {
|
||||
Audit audit = new Audit();
|
||||
audit.setDocId(docId);
|
||||
audit.setDocName(docName);
|
||||
audit.setMessage(message);
|
||||
audit.setPath(path);
|
||||
audit.setStatus(status);
|
||||
audit.setValue(value);
|
||||
return audit;
|
||||
}
|
||||
|
||||
public static void addAudit(AtlasSession session, Validation validation) {
|
||||
Audit audit = new Audit();
|
||||
audit.setDocId(validation.getDocId());
|
||||
audit.setDocName(validation.getDocName());
|
||||
audit.setMessage(validation.getMessage());
|
||||
audit.setStatus(AtlasUtil.toAuditStatus(validation.getStatus()));
|
||||
session.getAudits().getAudit().add(audit);
|
||||
}
|
||||
|
||||
public static void addAudits(AtlasInternalSession session, Field field, List<Audit> audits) {
|
||||
String docId = field.getDocId();
|
||||
String docName = getDocumentNameById(session, docId);
|
||||
for (Audit audit: audits) {
|
||||
audit.setDocId(docId);
|
||||
audit.setDocName(docName);
|
||||
session.getAudits().getAudit().add(audit);
|
||||
}
|
||||
}
|
||||
|
||||
public static AuditStatus toAuditStatus(ValidationStatus vstatus) {
|
||||
switch (vstatus) {
|
||||
case ERROR:
|
||||
return AuditStatus.ERROR;
|
||||
case WARN:
|
||||
return AuditStatus.WARN;
|
||||
case INFO:
|
||||
return AuditStatus.INFO;
|
||||
case ALL:
|
||||
return AuditStatus.ALL;
|
||||
case NONE:
|
||||
return AuditStatus.NONE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDocumentNameById(AtlasInternalSession session, String docId) {
|
||||
if (session == null || docId == null) {
|
||||
return null;
|
||||
}
|
||||
AtlasModule module = session.resolveModule(docId);
|
||||
return module != null ? module.getDocName() : null;
|
||||
}
|
||||
|
||||
protected static URL getResource(String scannedPath) {
|
||||
URL url = null;
|
||||
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (classLoader == null) {
|
||||
classLoader = AtlasUtil.class.getClassLoader();
|
||||
}
|
||||
|
||||
if (classLoader != null) {
|
||||
url = classLoader.getResource(scannedPath);
|
||||
if (url != null) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
return ClassLoader.getSystemResource(scannedPath);
|
||||
}
|
||||
|
||||
protected static List<Class<?>> find(File file, String scannedPackage) {
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
String resource = scannedPackage + '.' + file.getName();
|
||||
if (file.isDirectory()) {
|
||||
for (File child : file.listFiles()) {
|
||||
classes.addAll(find(child, resource));
|
||||
}
|
||||
} else if (resource.endsWith(".class")) {
|
||||
int endIndex = resource.length() - ".class".length();
|
||||
String className = resource.substring(0, endIndex);
|
||||
try {
|
||||
classes.add(Class.forName(className));
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
protected static List<Class<?>> findClassesFromJar(URL jarFileUrl) {
|
||||
List<Class<?>> classNames = new ArrayList<Class<?>>();
|
||||
|
||||
JarURLConnection connection = null;
|
||||
|
||||
try {
|
||||
connection = (JarURLConnection) jarFileUrl.openConnection();
|
||||
} catch (IOException e) {
|
||||
LOG.warn(String.format("Unable to load classes from jar file=%s msg=%s", jarFileUrl, e.getMessage()), e);
|
||||
return classNames;
|
||||
}
|
||||
|
||||
try (ZipInputStream zip = new ZipInputStream(
|
||||
new FileInputStream(new File(connection.getJarFileURL().toURI())))) {
|
||||
for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
|
||||
if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
|
||||
String className = entry.getName().replace('/', '.');
|
||||
className = className.substring(0, className.length() - ".class".length());
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (classLoader == null) {
|
||||
classLoader = AtlasUtil.class.getClassLoader();
|
||||
}
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className, false, classLoader);
|
||||
classNames.add(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOG.warn(String.format("Unable to load class=%s from jar file=%s msg=%s", className,
|
||||
jarFileUrl, e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
LOG.warn(String.format("Unable to load classes from jar file=%s msg=%s", jarFileUrl, e.getMessage()), e);
|
||||
}
|
||||
return classNames;
|
||||
}
|
||||
|
||||
public static String getChainedMessage(Throwable t) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(t.getMessage());
|
||||
Throwable target = t;
|
||||
while((target = target.getCause()) != null) {
|
||||
if (target.getMessage() != null && !target.getMessage().isEmpty()) {
|
||||
buf.append(" - ");
|
||||
buf.append(target.getMessage());
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String escapeForUri(String source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return source.replaceAll(Pattern.quote("!"), "%21")
|
||||
.replaceAll(Pattern.quote("#"), "%23")
|
||||
.replaceAll(Pattern.quote("$"), "%24")
|
||||
.replaceAll(Pattern.quote("&"), "%26")
|
||||
.replaceAll(Pattern.quote("'"), "%27")
|
||||
.replaceAll(Pattern.quote("("), "%28")
|
||||
.replaceAll(Pattern.quote(")"), "%29")
|
||||
.replaceAll(Pattern.quote("*"), "%2A")
|
||||
.replaceAll(Pattern.quote("+"), "%2B")
|
||||
.replaceAll(Pattern.quote(","), "%2C")
|
||||
.replaceAll(Pattern.quote("/"), "%2F")
|
||||
.replaceAll(Pattern.quote(":"), "%3A")
|
||||
.replaceAll(Pattern.quote(";"), "%3B")
|
||||
.replaceAll(Pattern.quote("="), "%3D")
|
||||
.replaceAll(Pattern.quote("?"), "%3F")
|
||||
.replaceAll(Pattern.quote("@"), "%40")
|
||||
.replaceAll(Pattern.quote("["), "%5B")
|
||||
.replaceAll(Pattern.quote("]"), "%5D");
|
||||
}
|
||||
|
||||
public static String unescapeFromUri(String uri) {
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
return uri.replaceAll("%21", "!")
|
||||
.replaceAll("%23", "#")
|
||||
.replaceAll("%24", "$")
|
||||
.replaceAll("%26", "&")
|
||||
.replaceAll("%27", "'")
|
||||
.replaceAll("%28", "(")
|
||||
.replaceAll("%29", ")")
|
||||
.replaceAll("%2A", "*")
|
||||
.replaceAll("%2B", "+")
|
||||
.replaceAll("%2C", ",")
|
||||
.replaceAll("%2F", "/")
|
||||
.replaceAll("%3A", ":")
|
||||
.replaceAll("%3B", ";")
|
||||
.replaceAll("%3D", "=")
|
||||
.replaceAll("%3F", "?")
|
||||
.replaceAll("%40", "@")
|
||||
.replaceAll("%5B", "[")
|
||||
.replaceAll("%5D", "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete specified directory and the contents in it.
|
||||
* @see #deleteDirectoryContents
|
||||
* @param targetDir
|
||||
*/
|
||||
public static void deleteDirectory(File targetDir) {
|
||||
File[] allContents = targetDir.listFiles();
|
||||
if (allContents != null) {
|
||||
for (File file : allContents) {
|
||||
if (!file.isDirectory()) {
|
||||
file.delete();
|
||||
} else {
|
||||
deleteDirectory(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
targetDir.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all contents in the specified directory.
|
||||
*
|
||||
* @see #deleteDirectory
|
||||
* @param targetDir
|
||||
*/
|
||||
public static void deleteDirectoryContents(File targetDir) {
|
||||
File[] allContents = targetDir.listFiles();
|
||||
if (allContents != null) {
|
||||
for (File element : allContents) {
|
||||
if (element.isFile()) {
|
||||
element.delete();
|
||||
} else if (element.isDirectory()) {
|
||||
deleteDirectory(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public static void copyFile(Path sourcePath, Path destPath) throws IOException {
|
||||
File source = new File(sourcePath.toString());
|
||||
File dest = new File(destPath.toString());
|
||||
|
||||
if (!dest.exists()) {
|
||||
dest.createNewFile();
|
||||
}
|
||||
|
||||
try (InputStream in = new FileInputStream(source);
|
||||
OutputStream out = new FileOutputStream(dest)) {
|
||||
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.management.openmbean.TabularData;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.mxbean.AtlasModuleMXBean;
|
||||
import io.atlasmap.spi.AtlasCollectionHelper;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasFieldActionService;
|
||||
import io.atlasmap.spi.AtlasInternalSession;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.AtlasModuleDetail;
|
||||
import io.atlasmap.spi.AtlasModuleMode;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.DataSourceMetadata;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
import io.atlasmap.v2.LookupEntry;
|
||||
import io.atlasmap.v2.LookupTable;
|
||||
import io.atlasmap.v2.SimpleField;
|
||||
|
||||
public abstract class BaseAtlasModule implements AtlasModule, AtlasModuleMXBean {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BaseAtlasModule.class);
|
||||
|
||||
private boolean automaticallyProcessOutputFieldActions = true;
|
||||
private AtlasConversionService atlasConversionService = null;
|
||||
private AtlasFieldActionService atlasFieldActionService = null;
|
||||
private AtlasCollectionHelper collectionHelper = null;
|
||||
private AtlasModuleMode atlasModuleMode = AtlasModuleMode.UNSET;
|
||||
private String docId;
|
||||
private String docName;
|
||||
private String uri;
|
||||
private String uriDataType;
|
||||
private Map<String,String> uriParameters = new HashMap<>();
|
||||
private ClassLoader classLoader;
|
||||
private DataSourceMetadata dataSourceMetadata;
|
||||
|
||||
@Override
|
||||
public void init() throws AtlasException {
|
||||
// no-op now
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws AtlasException {
|
||||
// no-op now
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostValidation(AtlasInternalSession session) throws AtlasException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{}: processPostValidation completed", getDocId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateTargetField(AtlasInternalSession session) throws AtlasException {
|
||||
Field sourceField = session.head().getSourceField();
|
||||
Field targetField = session.head().getTargetField();
|
||||
Object targetValue = null;
|
||||
if (targetField.getFieldType() == null
|
||||
|| (sourceField.getFieldType() != null && sourceField.getFieldType().equals(targetField.getFieldType()))) {
|
||||
targetValue = sourceField.getValue();
|
||||
} else if (sourceField.getValue() != null) {
|
||||
try {
|
||||
targetValue = getConversionService().convertType(sourceField.getValue(), sourceField.getFormat(),
|
||||
targetField.getFieldType(), targetField.getFormat());
|
||||
} catch (AtlasConversionException e) {
|
||||
AtlasUtil.addAudit(session, targetField,
|
||||
String.format("Unable to auto-convert for sT=%s tT=%s tF=%s msg=%s", sourceField.getFieldType(),
|
||||
targetField.getFieldType(), targetField.getPath(), e.getMessage()),
|
||||
AuditStatus.ERROR, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
targetField.setValue(targetValue);
|
||||
targetField.setStatus(sourceField.getStatus());
|
||||
|
||||
LookupTable lookupTable = session.head().getLookupTable();
|
||||
if (lookupTable != null) {
|
||||
processLookupField(session, lookupTable, targetField.getValue(), targetField);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processLookupField(AtlasInternalSession session, LookupTable lookupTable, Object sourceValue,
|
||||
Field targetField) throws AtlasException {
|
||||
String lookupValue = null;
|
||||
FieldType lookupType = null;
|
||||
for (LookupEntry lkp : lookupTable.getLookupEntry()) {
|
||||
if (lkp.getSourceValue().equals(sourceValue)) {
|
||||
lookupValue = lkp.getTargetValue();
|
||||
lookupType = lkp.getTargetType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Object targetValue = null;
|
||||
if (lookupType == null || FieldType.STRING.equals(lookupType)) {
|
||||
targetValue = lookupValue;
|
||||
} else {
|
||||
targetValue = atlasConversionService.convertType(lookupValue, FieldType.STRING, lookupType);
|
||||
}
|
||||
|
||||
FieldType targetFieldType = targetField.getFieldType();
|
||||
if (targetFieldType == null || targetFieldType == FieldType.COMPLEX) {
|
||||
targetField.setFieldType(lookupType != null ? lookupType : FieldType.STRING);
|
||||
targetFieldType = targetField.getFieldType();
|
||||
}
|
||||
if (targetFieldType != null && !targetFieldType.equals(lookupType)) {
|
||||
targetValue = atlasConversionService.convertType(targetValue, lookupType, targetField.getFieldType());
|
||||
}
|
||||
|
||||
targetField.setValue(targetValue);
|
||||
}
|
||||
|
||||
protected Field applyTargetFieldActions(AtlasInternalSession session) throws AtlasException {
|
||||
Field field = session.head().getTargetField();
|
||||
if (isAutomaticallyProcessOutputFieldActions() && field.getActions() != null
|
||||
&& field.getActions() != null) {
|
||||
return getFieldActionService().processActions(session, field);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
protected Field applySourceFieldActions(AtlasInternalSession session) throws AtlasException {
|
||||
Field field = session.head().getSourceField();
|
||||
if (field.getActions() != null && field.getActions() != null) {
|
||||
return getFieldActionService().processActions(session, field);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasModuleMode getMode() {
|
||||
return this.atlasModuleMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMode(AtlasModuleMode atlasModuleMode) {
|
||||
this.atlasModuleMode = atlasModuleMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isStatisticsSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isStatisticsEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AtlasModuleMode> listSupportedModes() {
|
||||
return Arrays.asList(AtlasModuleMode.SOURCE, AtlasModuleMode.TARGET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasConversionService getConversionService() {
|
||||
return atlasConversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasCollectionHelper getCollectionHelper() {
|
||||
return collectionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocId() {
|
||||
return docId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocId(String docId) {
|
||||
this.docId = docId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
this.uriDataType = AtlasUtil.getUriDataType(uri);
|
||||
this.uriParameters = AtlasUtil.getUriParameters(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUriDataType() {
|
||||
return this.uriDataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUriParameters() {
|
||||
return Collections.unmodifiableMap(uriParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversionService(AtlasConversionService atlasConversionService) {
|
||||
this.atlasConversionService = atlasConversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasFieldActionService getFieldActionService() {
|
||||
return this.atlasFieldActionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFieldActionService(AtlasFieldActionService atlasFieldActionService) {
|
||||
this.atlasFieldActionService = atlasFieldActionService;
|
||||
this.collectionHelper = createCollectionHelper(atlasFieldActionService);
|
||||
}
|
||||
|
||||
protected AtlasCollectionHelper createCollectionHelper(AtlasFieldActionService fieldActionService) {
|
||||
return new DefaultAtlasCollectionHelper(fieldActionService);
|
||||
}
|
||||
|
||||
public boolean isAutomaticallyProcessOutputFieldActions() {
|
||||
return automaticallyProcessOutputFieldActions;
|
||||
}
|
||||
|
||||
public void setAutomaticallyProcessOutputFieldActions(boolean automaticallyProcessOutputFieldActions) {
|
||||
this.automaticallyProcessOutputFieldActions = automaticallyProcessOutputFieldActions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSupportedField(Field field) {
|
||||
return field instanceof SimpleField || field instanceof FieldGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDataSourceMetadata(DataSourceMetadata meta) {
|
||||
this.dataSourceMetadata = meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceMetadata getDataSourceMetadata() {
|
||||
return this.dataSourceMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocName(String docName) {
|
||||
this.docName = docName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocName() {
|
||||
return this.docName;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// JMX MBean methods
|
||||
//-----------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean isSourceSupported() {
|
||||
return Arrays.asList(this.getClass().getAnnotation(AtlasModuleDetail.class).modes()).contains("SOURCE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTargetSupported() {
|
||||
return Arrays.asList(this.getClass().getAnnotation(AtlasModuleDetail.class).modes()).contains("TARGET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return this.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDataFormats() {
|
||||
return this.getClass().getAnnotation(AtlasModuleDetail.class).dataFormats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModeName() {
|
||||
return this.atlasModuleMode.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.getClass().getAnnotation(AtlasModuleDetail.class).name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPackageNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceErrorCount() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceCount() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceMaxExecutionTime() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceMinExecutionTime() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceSuccessCount() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceTotalExecutionTime() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTargetCount() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTargetErrorCount() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTargetMaxExecutionTime() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTargetMinExecutionTime() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTargetSuccessCount() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTargetTotalExecutionTime() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabularData readAndResetStatistics() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatisticsEnabled(boolean enabled) {
|
||||
LOG.warn("Statistics is not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import io.atlasmap.spi.FunctionFactory;
|
||||
|
||||
public abstract class BaseFunctionFactory implements FunctionFactory {
|
||||
|
||||
public String getName() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
public abstract class CompoundClassLoader extends ClassLoader {
|
||||
|
||||
public abstract void addAlternativeLoader(ClassLoader cl);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.spi.AtlasCollectionHelper;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasFieldActionService;
|
||||
import io.atlasmap.spi.AtlasInternalSession;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.AtlasModuleDetail;
|
||||
import io.atlasmap.spi.AtlasModuleMode;
|
||||
import io.atlasmap.v2.ConstantField;
|
||||
import io.atlasmap.v2.DataSourceMetadata;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
@AtlasModuleDetail(name = "ConstantModule", uri = "", modes = { "SOURCE" }, dataFormats = {}, configPackages = {})
|
||||
public class ConstantModule implements AtlasModule {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ConstantModule.class);
|
||||
|
||||
private AtlasConversionService conversionService;
|
||||
private AtlasFieldActionService fieldActionService;
|
||||
private AtlasCollectionHelper collectionHelper;
|
||||
private ClassLoader classLoader;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreValidation(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreSourceExecution(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSourceValue(AtlasInternalSession session) throws AtlasException {
|
||||
Field sourceField = session.head().getSourceField();
|
||||
if (!(sourceField instanceof ConstantField)) {
|
||||
return;
|
||||
}
|
||||
if (getConversionService() != null && sourceField.getFieldType() != null && sourceField.getValue() != null) {
|
||||
sourceField.setValue(getConversionService().convertType(sourceField.getValue(), null,
|
||||
getConversionService().classFromFieldType(sourceField.getFieldType()), null));
|
||||
} else if (sourceField.getFieldType() == null) {
|
||||
sourceField.setFieldType(FieldType.STRING);
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Processed source ConstantField sPath=" + sourceField.getPath() + " sV=" + sourceField.getValue()
|
||||
+ " sT=" + sourceField.getFieldType() + " docId: " + sourceField.getDocId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostSourceExecution(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreTargetExecution(AtlasInternalSession session) throws AtlasException {
|
||||
throw new UnsupportedOperationException("ConstantField cannot be placed as a target field");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateTargetField(AtlasInternalSession session) throws AtlasException {
|
||||
throw new UnsupportedOperationException("ConstantField cannot be placed as a target field");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTargetValue(AtlasInternalSession session) throws AtlasException {
|
||||
throw new UnsupportedOperationException("ConstantField cannot be placed as a target field");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostTargetExecution(AtlasInternalSession session) throws AtlasException {
|
||||
throw new UnsupportedOperationException("ConstantField cannot be placed as a target field");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostValidation(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasModuleMode getMode() {
|
||||
return AtlasModuleMode.SOURCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMode(AtlasModuleMode atlasModuleMode) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasConversionService getConversionService() {
|
||||
return this.conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversionService(AtlasConversionService atlasConversionService) {
|
||||
this.conversionService = atlasConversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AtlasModuleMode> listSupportedModes() {
|
||||
return Arrays.asList(new AtlasModuleMode[] { AtlasModuleMode.SOURCE });
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocId(String docId) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUri(String uri) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isStatisticsSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isStatisticsEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSupportedField(Field field) {
|
||||
return field instanceof ConstantField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field cloneField(Field field) throws AtlasException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasFieldActionService getFieldActionService() {
|
||||
return this.fieldActionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFieldActionService(AtlasFieldActionService atlasFieldActionService) {
|
||||
this.fieldActionService = atlasFieldActionService;
|
||||
this.collectionHelper = new DefaultAtlasCollectionHelper(atlasFieldActionService);
|
||||
}
|
||||
|
||||
public AtlasCollectionHelper getCollectionHelper() {
|
||||
return collectionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUriDataType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUriParameters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDataSourceMetadata(DataSourceMetadata meta) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceMetadata getDataSourceMetadata() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocName(String docName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocName() {
|
||||
return "Constants";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantField createField() {
|
||||
return new ConstantField();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.spi.AtlasCollectionHelper;
|
||||
import io.atlasmap.spi.AtlasFieldActionService;
|
||||
import io.atlasmap.v2.Action;
|
||||
import io.atlasmap.v2.ActionDetail;
|
||||
import io.atlasmap.v2.CollectionType;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.Multiplicity;
|
||||
|
||||
public class DefaultAtlasCollectionHelper implements AtlasCollectionHelper {
|
||||
|
||||
private AtlasFieldActionService fieldActionService;
|
||||
|
||||
public DefaultAtlasCollectionHelper() {
|
||||
this.fieldActionService = DefaultAtlasFieldActionService.getInstance();
|
||||
}
|
||||
|
||||
public DefaultAtlasCollectionHelper(AtlasFieldActionService fieldActionService) {
|
||||
this.fieldActionService = fieldActionService;
|
||||
}
|
||||
|
||||
protected AtlasPath createTargetAtlasPath(String path) {
|
||||
return new AtlasPath(path);
|
||||
}
|
||||
|
||||
public int determineTargetCollectionCount(Field targetField) {
|
||||
AtlasPath targetPath = createTargetAtlasPath(targetField.getPath());
|
||||
int targetCollectionCount = targetPath.getCollectionSegmentCount();
|
||||
if (targetField.getIndex() != null) {
|
||||
targetCollectionCount++; //adjust based on index
|
||||
}
|
||||
return targetCollectionCount;
|
||||
}
|
||||
|
||||
public int determineSourceCollectionCount(Field sourceParentField, Field sourceField) {
|
||||
AtlasPath sourcePath = new AtlasPath(sourceField.getPath());
|
||||
int sourceCollectionCount = sourcePath.getCollectionSegmentCount();
|
||||
sourceCollectionCount += getCollectionCountAdjustmentForActions(sourceParentField);
|
||||
sourceCollectionCount += getCollectionCountAdjustmentForActions(sourceField);
|
||||
if (sourceField.getIndex() != null) {
|
||||
sourceCollectionCount--; //adjust based on index
|
||||
}
|
||||
return sourceCollectionCount;
|
||||
}
|
||||
|
||||
private int getCollectionCountAdjustmentForActions(Field sourceField) {
|
||||
int sourceCollectionCount = 0;
|
||||
if (sourceField != null && sourceField.getActions() != null) {
|
||||
for (Action action : sourceField.getActions()) {
|
||||
ActionDetail actionDetail = null;
|
||||
try {
|
||||
actionDetail = fieldActionService.findActionDetail(action, sourceField.getFieldType());
|
||||
} catch (AtlasException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (actionDetail != null) {
|
||||
if (Multiplicity.ONE_TO_MANY.equals(actionDetail.getMultiplicity())) {
|
||||
sourceCollectionCount++;
|
||||
} else if (Multiplicity.MANY_TO_ONE.equals(actionDetail.getMultiplicity())) {
|
||||
sourceCollectionCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sourceCollectionCount;
|
||||
}
|
||||
|
||||
public void copyCollectionIndexes(Field sourceParentField, Field sourceField, Field targetField, Field previousTargetField) {
|
||||
AtlasPath sourcePath = new AtlasPath(sourceField.getPath());
|
||||
AtlasPath targetPath = createTargetAtlasPath(targetField.getPath());
|
||||
int targetCollectionCount = determineTargetCollectionCount(targetField);
|
||||
int sourceCollectionCount = determineSourceCollectionCount(sourceParentField, sourceField);
|
||||
int targetIndex = 0;
|
||||
int collectionCount = 0;
|
||||
List<AtlasPath.SegmentContext> targetSegments = targetPath.getSegments(true);
|
||||
|
||||
if (targetCollectionCount > sourceCollectionCount) {
|
||||
//Put 0 index in excessive target collections, if targetCollectionCount > sourceCollectionCount
|
||||
while (collectionCount < targetCollectionCount - sourceCollectionCount) {
|
||||
AtlasPath.SegmentContext targetSegment = targetSegments.get(targetIndex);
|
||||
if (targetSegment.getCollectionType() != CollectionType.NONE) {
|
||||
targetPath.setCollectionIndex(targetIndex, 0);
|
||||
collectionCount++;
|
||||
}
|
||||
targetIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
AtlasPath previousTargetPath = previousTargetField != null ? createTargetAtlasPath(previousTargetField.getPath()) : null;
|
||||
List<AtlasPath.SegmentContext> sourceCollectionSegments = sourcePath.getCollectionSegments(true);
|
||||
AtlasPath.SegmentContext lastSourceSegment = sourcePath.getLastSegment();
|
||||
AtlasPath.SegmentContext lastTargetCollectionSegment = targetPath.getLastCollectionSegment();
|
||||
for (AtlasPath.SegmentContext sourceSegment : sourcePath.getSegments(true)) {
|
||||
if (sourceSegment.getCollectionType() == CollectionType.NONE && sourceSegment != lastSourceSegment) {
|
||||
//always process last segment even if not a collection (in case e.g. split has been applied)
|
||||
continue;
|
||||
}
|
||||
|
||||
while (targetSegments.size() > targetIndex) {
|
||||
AtlasPath.SegmentContext targetSegment = targetSegments.get(targetIndex);
|
||||
if (targetSegment.getCollectionType() != CollectionType.NONE) {
|
||||
collectionCount++;
|
||||
if (sourceSegment.getCollectionIndex() != null) {
|
||||
if (sourceCollectionCount > targetCollectionCount && targetCollectionCount == collectionCount) {
|
||||
//if needs to flatten excessive rightmost source collections
|
||||
int nextCollectionIndex = determineNextCollectionIndex(previousTargetPath, sourceCollectionSegments);
|
||||
targetPath.setCollectionIndex(targetIndex, nextCollectionIndex);
|
||||
} else {
|
||||
targetPath.setCollectionIndex(targetIndex, sourceSegment.getCollectionIndex());
|
||||
}
|
||||
|
||||
targetIndex++;
|
||||
break;
|
||||
} else if (targetSegment == lastTargetCollectionSegment && sourceParentField instanceof FieldGroup) {
|
||||
//if the last collection target segment, but no collection index specified (e.g. after split)
|
||||
int nextCollectionIndex = determineNextCollectionIndex(previousTargetPath, sourceCollectionSegments);
|
||||
targetPath.setCollectionIndex(targetIndex, nextCollectionIndex);
|
||||
|
||||
targetIndex++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
targetIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
targetField.setPath(targetPath.toString());
|
||||
}
|
||||
|
||||
private int determineNextCollectionIndex(AtlasPath previousTargetPath, List<AtlasPath.SegmentContext> sourceCollectionSegments) {
|
||||
int nextCollectionIndex = 0;
|
||||
if (previousTargetPath != null) {
|
||||
List<AtlasPath.SegmentContext> previousTargetCollectionSegments = previousTargetPath.getCollectionSegments(true);
|
||||
boolean parentIndexesChanged = false;
|
||||
for (int i = previousTargetCollectionSegments.size() - 2; i >= 0; i--) {
|
||||
if (!previousTargetCollectionSegments.get(i).getCollectionIndex()
|
||||
.equals(sourceCollectionSegments.get(i).getCollectionIndex())) {
|
||||
parentIndexesChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parentIndexesChanged) {
|
||||
//determine previous collection index
|
||||
nextCollectionIndex = previousTargetCollectionSegments
|
||||
.get(previousTargetCollectionSegments.size() - 1).getCollectionIndex();
|
||||
nextCollectionIndex++;
|
||||
}
|
||||
}
|
||||
return nextCollectionIndex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import io.atlasmap.spi.AtlasCombineStrategy;
|
||||
import io.atlasmap.spi.StringDelimiter;
|
||||
|
||||
public class DefaultAtlasCombineStrategy implements AtlasCombineStrategy {
|
||||
|
||||
public static final StringDelimiter DEFAULT_COMBINE_DELIMITER = StringDelimiter.SPACE;
|
||||
public static final Integer DEFAULT_COMBINE_LIMIT = 512;
|
||||
private StringDelimiter delimiter = DEFAULT_COMBINE_DELIMITER;
|
||||
private Integer limit = DEFAULT_COMBINE_LIMIT;
|
||||
private boolean disableAutoTrim = false;
|
||||
private boolean disableAddDelimiterOnNull = false;
|
||||
|
||||
@Override
|
||||
public StringDelimiter getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDelimiter(StringDelimiter delimiter) {
|
||||
this.delimiter = delimiter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLimit(Integer limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public boolean isDisableAutoTrim() {
|
||||
return disableAutoTrim;
|
||||
}
|
||||
|
||||
public void setDisableAutoTrim(boolean disableAutoTrim) {
|
||||
this.disableAutoTrim = disableAutoTrim;
|
||||
}
|
||||
|
||||
public boolean isDisableAddDelimiterOnNull() {
|
||||
return disableAddDelimiterOnNull;
|
||||
}
|
||||
|
||||
public void setDisableAddDelimiterOnNull(boolean disableAddDelimiterOnNull) {
|
||||
this.disableAddDelimiterOnNull = disableAddDelimiterOnNull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String combineValues(Map<Integer, String> values) {
|
||||
return combineValues(values, getDelimiter(), getLimit());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String combineValues(Map<Integer, String> values, StringDelimiter delimiter) {
|
||||
return combineValues(values, delimiter, getLimit());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String combineValues(Map<Integer, String> values, StringDelimiter delimiter, Integer limit) {
|
||||
if (values == null || values.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String combinedString = "";
|
||||
if (values.size() == 1) {
|
||||
combinedString = values.get(0);
|
||||
return combinedString;
|
||||
}
|
||||
|
||||
Map<Integer, String> sortedMap = sortByKey(values);
|
||||
Integer last = sortedMap.keySet().toArray(new Integer[0])[sortedMap.size()-1];
|
||||
|
||||
boolean first = true;
|
||||
int count = 0;
|
||||
for (int i=0; i<=last; i++) {
|
||||
String value = sortedMap.get(i);
|
||||
if (first) {
|
||||
first = false;
|
||||
if (value == null) {
|
||||
continue;
|
||||
} else if (isDisableAutoTrim()) {
|
||||
combinedString = combinedString.concat(value);
|
||||
} else {
|
||||
combinedString = combinedString.concat(value.trim());
|
||||
}
|
||||
} else {
|
||||
if (value == null) {
|
||||
if (!disableAddDelimiterOnNull) {
|
||||
combinedString = combinedString.concat((delimiter != null ? delimiter.getValue() : DEFAULT_COMBINE_DELIMITER.getValue()));
|
||||
}
|
||||
} else if (isDisableAutoTrim()) {
|
||||
combinedString = combinedString.concat((delimiter != null ? delimiter.getValue() : DEFAULT_COMBINE_DELIMITER.getValue()))
|
||||
.concat(value);
|
||||
} else {
|
||||
combinedString = combinedString.concat((delimiter != null ? delimiter.getValue() : DEFAULT_COMBINE_DELIMITER.getValue()))
|
||||
.concat(value.trim());
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
if (count >= (limit != null ? limit : DEFAULT_COMBINE_LIMIT)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return combinedString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String combineValues(Map<Integer, String> values, String delimiter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static Map<Integer, String> sortByKey(Map<Integer, String> map) {
|
||||
TreeMap<Integer, String> treeMap = new TreeMap<>((key1, key2) -> {
|
||||
if (key1 == null && key2 == null) {
|
||||
return 0;
|
||||
} else if (key1 == null) {
|
||||
return -1;// 1 or -1; whatever, the null value can be retrieved only with .get(null)
|
||||
} else if (key2 == null) {
|
||||
return 1;
|
||||
} else {
|
||||
return key1.compareTo(key2);
|
||||
}
|
||||
});
|
||||
treeMap.putAll(map);
|
||||
return treeMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class DefaultAtlasCompoundClassLoader extends CompoundClassLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CompoundClassLoader.class);
|
||||
|
||||
private Set<ClassLoader> delegates = new LinkedHashSet<>();
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
for (ClassLoader cl : classLoaders()) {
|
||||
try {
|
||||
return cl.loadClass(name);
|
||||
} catch (Throwable t) {
|
||||
LOG.debug("Class '{}' was not found with ClassLoader '{}': {}", name, cl);
|
||||
LOG.debug(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
private Set<ClassLoader> classLoaders() {
|
||||
Set<ClassLoader> answer = new LinkedHashSet<>(delegates);
|
||||
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
|
||||
if (tccl != null && !tccl.equals(this)) {
|
||||
answer.add(tccl);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
for (ClassLoader cl : classLoaders()) {
|
||||
URL url = cl.getResource(name);
|
||||
if (url != null) {
|
||||
return url;
|
||||
}
|
||||
LOG.debug("Resource '{}' was not found with ClassLoader '{}': {}", name, cl);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> getResources(String name) {
|
||||
Set<URL> answer = new LinkedHashSet<>();
|
||||
for (ClassLoader cl : classLoaders()) {
|
||||
try {
|
||||
Enumeration<URL> urls = cl.getResources(name);
|
||||
while (urls != null && urls.hasMoreElements()) {
|
||||
answer.add(urls.nextElement());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("I/O error while looking for a resource '{}' with ClassLoader '{}': {}", name, cl);
|
||||
LOG.debug(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return Collections.enumeration(answer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addAlternativeLoader(ClassLoader cl) {
|
||||
if (cl != null && !this.equals(cl)) {
|
||||
delegates.add(cl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,546 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasContextFactory;
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.api.AtlasValidationService;
|
||||
import io.atlasmap.mxbean.AtlasContextFactoryMXBean;
|
||||
import io.atlasmap.spi.AtlasCombineStrategy;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.AtlasModuleDetail;
|
||||
import io.atlasmap.spi.AtlasModuleInfo;
|
||||
import io.atlasmap.spi.AtlasModuleInfoRegistry;
|
||||
import io.atlasmap.spi.AtlasPropertyStrategy;
|
||||
import io.atlasmap.spi.AtlasSeparateStrategy;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
|
||||
public class DefaultAtlasContextFactory implements AtlasContextFactory, AtlasContextFactoryMXBean {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasContextFactory.class);
|
||||
|
||||
private static DefaultAtlasContextFactory factory = null;
|
||||
private boolean initialized = false;
|
||||
private String uuid = null;
|
||||
private String threadName = null;
|
||||
private ObjectName objectName = null;
|
||||
private DefaultAtlasConversionService atlasConversionService = null;
|
||||
private DefaultAtlasFieldActionService atlasFieldActionService = null;
|
||||
private AtlasCombineStrategy atlasCombineStrategy = null;
|
||||
private AtlasPropertyStrategy atlasPropertyStrategy = null;
|
||||
private AtlasSeparateStrategy atlasSeparateStrategy = null;
|
||||
private AtlasValidationService atlasValidationService = null;
|
||||
private AtlasModuleInfoRegistry moduleInfoRegistry;
|
||||
private Map<String, String> properties = null;
|
||||
private CompoundClassLoader classLoader = null;
|
||||
|
||||
private DefaultAtlasContextFactory() {
|
||||
}
|
||||
|
||||
public static DefaultAtlasContextFactory getInstance() {
|
||||
return getInstance(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default singleton, possibly creating it if necessary.
|
||||
*
|
||||
* @param init if {@code true} the newly created {@link DefaultAtlasContextFactory} will be initialized upon
|
||||
* creation via {@link #init()}; otherwise, the newly created {@link DefaultAtlasContextFactory} will not
|
||||
* be initialized upon creation via {@link #init()}
|
||||
* @return the singleton
|
||||
*/
|
||||
public static DefaultAtlasContextFactory getInstance(boolean init) {
|
||||
if (factory == null) {
|
||||
factory = new DefaultAtlasContextFactory();
|
||||
if (init) {
|
||||
factory.init();
|
||||
}
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init() {
|
||||
CompoundClassLoader cl = new DefaultAtlasCompoundClassLoader();
|
||||
cl.addAlternativeLoader(AtlasMapping.class.getClassLoader());
|
||||
init(cl);
|
||||
}
|
||||
|
||||
public synchronized void init(CompoundClassLoader cl) {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.threadName = Thread.currentThread().getName();
|
||||
this.classLoader = cl;
|
||||
try {
|
||||
this.properties = new HashMap<>();
|
||||
Properties props = new Properties();
|
||||
props.load(this.getClass().getClassLoader().getResourceAsStream("atlasmap.properties"));
|
||||
String version = props.getProperty(PROPERTY_ATLASMAP_CORE_VERSION);
|
||||
this.properties.put(PROPERTY_ATLASMAP_CORE_VERSION, version);
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Failed to read atlasmap.properties", e);
|
||||
}
|
||||
|
||||
this.atlasConversionService = DefaultAtlasConversionService.getInstance();
|
||||
this.atlasFieldActionService = DefaultAtlasFieldActionService.getInstance();
|
||||
this.atlasFieldActionService.init(this.classLoader);
|
||||
this.atlasCombineStrategy = new DefaultAtlasCombineStrategy();
|
||||
this.atlasPropertyStrategy = new DefaultAtlasPropertyStrategy();
|
||||
this.atlasSeparateStrategy = new DefaultAtlasSeparateStrategy();
|
||||
this.atlasValidationService = new DefaultAtlasValidationService();
|
||||
registerFactoryJmx(this);
|
||||
this.moduleInfoRegistry = new DefaultAtlasModuleInfoRegistry(this);
|
||||
loadModules("moduleClass", AtlasModule.class);
|
||||
this.initialized = true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
this.properties = new HashMap<>();
|
||||
properties.forEach((key, value) -> this.properties.put(key.toString(), value.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void destroy() {
|
||||
if (!this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
unloadModules();
|
||||
|
||||
try {
|
||||
if (ManagementFactory.getPlatformMBeanServer().isRegistered(getJmxObjectName())) {
|
||||
ManagementFactory.getPlatformMBeanServer().unregisterMBean(getJmxObjectName());
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Unregistered AtlasContextFactory with JMX");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unable to unregister with JMX", e);
|
||||
}
|
||||
|
||||
this.uuid = null;
|
||||
this.objectName = null;
|
||||
this.properties = null;
|
||||
this.atlasFieldActionService = null;
|
||||
this.atlasConversionService = null;
|
||||
this.atlasPropertyStrategy = null;
|
||||
this.atlasCombineStrategy = null;
|
||||
this.atlasSeparateStrategy = null;
|
||||
this.atlasValidationService = null;
|
||||
this.moduleInfoRegistry = null;
|
||||
this.classLoader = null;
|
||||
this.threadName = null;
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasContext createContext(File atlasMappingFile) throws AtlasException {
|
||||
if (atlasMappingFile == null) {
|
||||
throw new AtlasException("AtlasMappingFile must be specified");
|
||||
}
|
||||
|
||||
return createContext(atlasMappingFile.toURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasContext createContext(URI atlasMappingUri) throws AtlasException {
|
||||
if (atlasMappingUri == null) {
|
||||
throw new AtlasException("AtlasMappingUri must be specified");
|
||||
}
|
||||
DefaultAtlasContext context = new DefaultAtlasContext(this, atlasMappingUri);
|
||||
return context;
|
||||
}
|
||||
|
||||
public DefaultAtlasContext createContext(AtlasMapping mapping) throws AtlasException {
|
||||
DefaultAtlasContext context = new DefaultAtlasContext(this, mapping);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasContext createContext(Format format, InputStream stream) throws AtlasException {
|
||||
DefaultAtlasContext context = new DefaultAtlasContext(this, format, stream);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasPreviewContext createPreviewContext() {
|
||||
DefaultAtlasPreviewContext context = new DefaultAtlasPreviewContext(this);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return this.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThreadName() {
|
||||
return this.threadName;
|
||||
}
|
||||
|
||||
public void setThreadName(String threadName) {
|
||||
this.threadName = threadName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return this.getClass().getPackage().getImplementationVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
public ObjectName getJmxObjectName() {
|
||||
return this.objectName;
|
||||
}
|
||||
|
||||
public AtlasModuleInfoRegistry getModuleInfoRegistry() {
|
||||
return this.moduleInfoRegistry;
|
||||
}
|
||||
|
||||
public void setModuleInfoRegistry(AtlasModuleInfoRegistry registry) {
|
||||
this.moduleInfoRegistry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasConversionService getConversionService() {
|
||||
return this.atlasConversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasFieldActionService getFieldActionService() {
|
||||
return this.atlasFieldActionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasCombineStrategy getCombineStrategy() {
|
||||
return atlasCombineStrategy;
|
||||
}
|
||||
|
||||
public void setCombineStrategy(AtlasCombineStrategy atlasCombineStrategy) {
|
||||
this.atlasCombineStrategy = atlasCombineStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasPropertyStrategy getPropertyStrategy() {
|
||||
return atlasPropertyStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyStrategy(AtlasPropertyStrategy atlasPropertyStrategy) {
|
||||
this.atlasPropertyStrategy = atlasPropertyStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasSeparateStrategy getSeparateStrategy() {
|
||||
return atlasSeparateStrategy;
|
||||
}
|
||||
|
||||
public void setSeparateStrategy(AtlasSeparateStrategy atlasSeparateStrategy) {
|
||||
this.atlasSeparateStrategy = atlasSeparateStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasValidationService getValidationService() {
|
||||
return atlasValidationService;
|
||||
}
|
||||
|
||||
public void setValidationService(AtlasValidationService atlasValidationService) {
|
||||
this.atlasValidationService = atlasValidationService;
|
||||
}
|
||||
|
||||
public CompoundClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClassLoader(ClassLoader cl) {
|
||||
this.classLoader.addAlternativeLoader(cl);
|
||||
}
|
||||
|
||||
public void setClassLoader(CompoundClassLoader cl) {
|
||||
this.classLoader = cl;
|
||||
}
|
||||
|
||||
protected void loadModules(String moduleClassProperty, Class<?> moduleInterface) {
|
||||
Class<?> moduleClass = null;
|
||||
String moduleClassName = null;
|
||||
Set<String> serviceClasses = new HashSet<>();
|
||||
|
||||
try {
|
||||
//TODO Entaxy - add io.atlasmap.java.module.JavaModule when it is ready
|
||||
Enumeration<URL> urls = classLoader.getResources("META-INF/services/atlas/module/atlas.module");
|
||||
while (urls.hasMoreElements()) {
|
||||
URL tmp = urls.nextElement();
|
||||
Properties prop = AtlasUtil.loadPropertiesFromURL(tmp);
|
||||
String serviceClassPropertyValue = (String) prop.get(moduleClassProperty);
|
||||
String[] splitted = serviceClassPropertyValue != null ? serviceClassPropertyValue.split(",") : new String[0];
|
||||
for (String entry : splitted) {
|
||||
if (!AtlasUtil.isEmpty(entry)) {
|
||||
serviceClasses.add((entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Error loading module resources", e);
|
||||
}
|
||||
|
||||
for (String clazz : serviceClasses) {
|
||||
try {
|
||||
moduleClass = classLoader.loadClass(clazz);
|
||||
moduleClassName = moduleClass.getName();
|
||||
|
||||
if (isClassAtlasModule(moduleClass, moduleInterface)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<AtlasModule> atlasModuleClass = (Class<AtlasModule>) moduleClass;
|
||||
Constructor<AtlasModule> constructor = atlasModuleClass.getDeclaredConstructor();
|
||||
if (constructor != null) {
|
||||
AtlasModuleInfo module = new DefaultAtlasModuleInfo(getModuleName(moduleClass),
|
||||
getModuleUri(moduleClass), atlasModuleClass, constructor,
|
||||
getSupportedDataFormats(moduleClass), getConfigPackages(moduleClass));
|
||||
getModuleInfoRegistry().register(module);
|
||||
} else {
|
||||
LOG.warn("Invalid module class {}: constructor is not present", moduleClassName);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Invalid module class {}: unsupported AtlasModule", moduleClassName);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
LOG.warn(String.format("Invalid module class %s: constructor is not present.", moduleClassName), e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOG.warn(String.format("Invalid module class %s: not found in classLoader.", moduleClassName), e);
|
||||
} catch (Exception e) {
|
||||
LOG.warn(String.format("Invalid module class %s: unknown error.", moduleClassName), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Loaded: {} of {} detected modules", getModuleInfoRegistry().size(), serviceClasses.size());
|
||||
}
|
||||
}
|
||||
|
||||
protected void unloadModules() {
|
||||
if (getModuleInfoRegistry() == null) {
|
||||
return;
|
||||
}
|
||||
int moduleCount = getModuleInfoRegistry().size();
|
||||
getModuleInfoRegistry().unregisterAll();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Unloaded: {} modules", moduleCount);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isClassAtlasModule(Class<?> clazz, Class<?> moduleInterface) {
|
||||
if (clazz == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isAtlasModuleInterface(clazz, moduleInterface) && clazz.isAnnotationPresent(AtlasModuleDetail.class)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} is a '{}' implementation", clazz.getCanonicalName(), moduleInterface.getSimpleName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} is NOT a '{}' implementation", clazz.getCanonicalName(), moduleInterface.getSimpleName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isAtlasModuleInterface(Class<?> clazz, Class<?> moduleInterface) {
|
||||
if (clazz == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isIface = false;
|
||||
Class<?> superClazz = clazz.getSuperclass();
|
||||
if (superClazz != null) {
|
||||
isIface = isAtlasModuleInterface(superClazz, moduleInterface);
|
||||
}
|
||||
|
||||
Class<?>[] interfaces = clazz.getInterfaces();
|
||||
for (Class<?> iface : interfaces) {
|
||||
if (iface.equals(moduleInterface)) {
|
||||
isIface = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isIface;
|
||||
}
|
||||
|
||||
protected String getModuleUri(Class<?> clazz) {
|
||||
|
||||
AtlasModuleDetail detail = clazz.getAnnotation(AtlasModuleDetail.class);
|
||||
|
||||
if (detail != null) {
|
||||
return detail.uri();
|
||||
}
|
||||
|
||||
return "UNDEFINED";
|
||||
}
|
||||
|
||||
protected String getModuleName(Class<?> clazz) {
|
||||
|
||||
AtlasModuleDetail detail = clazz.getAnnotation(AtlasModuleDetail.class);
|
||||
|
||||
if (detail != null) {
|
||||
return detail.name();
|
||||
}
|
||||
|
||||
return "UNDEFINED-" + UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
protected List<String> getSupportedDataFormats(Class<?> clazz) {
|
||||
|
||||
List<String> dataFormats = null;
|
||||
AtlasModuleDetail detail = clazz.getAnnotation(AtlasModuleDetail.class);
|
||||
|
||||
if (detail != null) {
|
||||
dataFormats = new ArrayList<>();
|
||||
|
||||
String[] formats = detail.dataFormats();
|
||||
|
||||
for (String format : formats) {
|
||||
dataFormats.add(format.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Module: {} supports data formats: {}", clazz.getCanonicalName(), dataFormats);
|
||||
}
|
||||
|
||||
return dataFormats;
|
||||
}
|
||||
|
||||
protected List<String> getConfigPackages(Class<?> clazz) {
|
||||
|
||||
List<String> configPackages = null;
|
||||
AtlasModuleDetail detail = clazz.getAnnotation(AtlasModuleDetail.class);
|
||||
|
||||
if (detail != null) {
|
||||
configPackages = new ArrayList<>();
|
||||
|
||||
String[] packages = detail.configPackages();
|
||||
|
||||
for (String pkg : packages) {
|
||||
configPackages.add(pkg.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Module: {} config packages: {}", clazz.getCanonicalName(), configPackages);
|
||||
}
|
||||
|
||||
return configPackages;
|
||||
}
|
||||
|
||||
protected List<String> getAllModuleConfigPackages(AtlasModuleInfoRegistry registry) {
|
||||
List<String> pkgs = new ArrayList<>();
|
||||
for (AtlasModuleInfo moduleInfo : registry.getAll()) {
|
||||
pkgs.addAll(Arrays.asList(moduleInfo.getPackageNames()));
|
||||
}
|
||||
return pkgs;
|
||||
}
|
||||
|
||||
protected void registerFactoryJmx(DefaultAtlasContextFactory factory) {
|
||||
if (factory == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
factory.setObjectName();
|
||||
if (!ManagementFactory.getPlatformMBeanServer().isRegistered(factory.getJmxObjectName())) {
|
||||
ManagementFactory.getPlatformMBeanServer().registerMBean(factory, factory.getJmxObjectName());
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Registered AtlasContextFactory with JMX");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unable to resgister DefaultAtlasContextFactory with JMX", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setObjectName() throws MalformedObjectNameException {
|
||||
this.objectName = new ObjectName(String.format("io.atlasmap:type=AtlasServiceFactory,factoryUuid=%s", getUuid()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,622 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import static java.util.Objects.hash;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
|
||||
public class DefaultAtlasConversionService implements AtlasConversionService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasConversionService.class);
|
||||
private static final Set<String> PRIMITIVE_CLASSNAMES = Collections.unmodifiableSet(
|
||||
new HashSet<>(Arrays.asList("boolean", "byte", "char", "double", "float", "int", "long", "short")));
|
||||
private static final Set<FieldType> PRIMITIVE_FIELDTYPES = Collections.unmodifiableSet(new HashSet<>(
|
||||
Arrays.asList(FieldType.BOOLEAN, FieldType.BYTE, FieldType.CHAR, FieldType.DECIMAL, FieldType.DOUBLE,
|
||||
FieldType.FLOAT, FieldType.INTEGER, FieldType.LONG, FieldType.SHORT, FieldType.STRING)));
|
||||
private static final Set<String> BOXED_PRIMITIVE_CLASSNAMES = Collections.unmodifiableSet(new HashSet<>(
|
||||
Arrays.asList("java.lang.Boolean", "java.lang.Byte", "java.lang.Character", "java.lang.Double",
|
||||
"java.lang.Float", "java.lang.Integer", "java.lang.Long", "java.lang.Short", "java.lang.String")));
|
||||
|
||||
private static volatile DefaultAtlasConversionService instance = null;
|
||||
private static final Object SINGLETON_LOCK = new Object();
|
||||
|
||||
private Map<ConverterKey, ConverterMethodHolder> converterMethods = null;
|
||||
private Map<ConverterKey, ConverterMethodHolder> customConverterMethods = null;
|
||||
|
||||
// Used as the lookup key in the converter methods map
|
||||
private class ConverterKey {
|
||||
private String sourceClassName;
|
||||
private String targetClassName;
|
||||
|
||||
public ConverterKey(String sourceClassName, String targetClassName) {
|
||||
this.sourceClassName = sourceClassName;
|
||||
this.targetClassName = targetClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && obj instanceof ConverterKey) {
|
||||
ConverterKey s = (ConverterKey) obj;
|
||||
return sourceClassName.equals(s.sourceClassName) && targetClassName.equals(s.targetClassName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash(sourceClassName, targetClassName);
|
||||
}
|
||||
}
|
||||
|
||||
// used to hold converter and method for future reflection use
|
||||
private class ConverterMethodHolder {
|
||||
private AtlasConverter<?> converter;
|
||||
private Method method;
|
||||
private boolean staticMethod;
|
||||
private boolean containsFormat;
|
||||
|
||||
public ConverterMethodHolder(AtlasConverter<?> converter, Method method, boolean staticMethod,
|
||||
boolean containsFormat) {
|
||||
this.converter = converter;
|
||||
this.method = method;
|
||||
this.staticMethod = staticMethod;
|
||||
this.containsFormat = containsFormat;
|
||||
}
|
||||
|
||||
public AtlasConverter<?> getConverter() {
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
|
||||
private DefaultAtlasConversionService() {
|
||||
}
|
||||
|
||||
public static DefaultAtlasConversionService getInstance() {
|
||||
DefaultAtlasConversionService result = instance;
|
||||
if (result == null) {
|
||||
synchronized (SINGLETON_LOCK) {
|
||||
result = instance;
|
||||
if (result == null) {
|
||||
result = new DefaultAtlasConversionService();
|
||||
result.init();
|
||||
instance = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Set<String> listPrimitiveClassNames() {
|
||||
return PRIMITIVE_CLASSNAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AtlasConverter<?>> findMatchingConverter(FieldType source, FieldType target) {
|
||||
|
||||
// get the default types
|
||||
Class<?> sourceClass = classFromFieldType(source);
|
||||
Class<?> targetClass = classFromFieldType(target);
|
||||
|
||||
if (sourceClass != null && targetClass != null) {
|
||||
return findMatchingConverter(sourceClass.getCanonicalName(), targetClass.getCanonicalName());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AtlasConverter<?>> findMatchingConverter(String sourceClassName, String targetClassName) {
|
||||
ConverterKey converterKey = new ConverterKey(sourceClassName, targetClassName);
|
||||
if (customConverterMethods.containsKey(converterKey)) {
|
||||
return Optional.of(customConverterMethods.get(converterKey).getConverter());
|
||||
} else if (converterMethods.containsKey(converterKey)) {
|
||||
return Optional.of(converterMethods.get(converterKey).getConverter());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
loadConverters();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void loadConverters() {
|
||||
ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
final ServiceLoader<AtlasConverter> converterServiceLoader = ServiceLoader.load(AtlasConverter.class,
|
||||
classLoader);
|
||||
final ServiceLoader<io.atlasmap.api.AtlasConverter> compat = ServiceLoader.load(io.atlasmap.api.AtlasConverter.class,
|
||||
classLoader);
|
||||
|
||||
// used to load up methods first;
|
||||
Map<ConverterKey, ConverterMethodHolder> methodsLoadMap = new LinkedHashMap<>();
|
||||
Map<ConverterKey, ConverterMethodHolder> customMethodsLoadMap = new LinkedHashMap<>();
|
||||
|
||||
converterServiceLoader.forEach(atlasConverter -> loadConverterMethod(atlasConverter, methodsLoadMap, customMethodsLoadMap));
|
||||
compat.forEach(atlasConverter -> loadConverterMethod(atlasConverter, methodsLoadMap, customMethodsLoadMap));
|
||||
|
||||
if (!methodsLoadMap.isEmpty()) {
|
||||
converterMethods = Collections.unmodifiableMap(methodsLoadMap);
|
||||
}
|
||||
if (!methodsLoadMap.isEmpty()) {
|
||||
customConverterMethods = Collections.unmodifiableMap(customMethodsLoadMap);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadConverterMethod(AtlasConverter<?> atlasConverter,
|
||||
Map<ConverterKey, ConverterMethodHolder> methodsLoadMap, Map<ConverterKey, ConverterMethodHolder> customMethodsLoadMap) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Loading converter : " + atlasConverter.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
boolean inbuiltConverter = atlasConverter.getClass().getPackage().getName().startsWith("io.atlasmap");
|
||||
|
||||
Class<?> klass = atlasConverter.getClass();
|
||||
// collect all the specific conversion methods on the class
|
||||
while (klass != Object.class) {
|
||||
final List<Method> allMethods = new ArrayList<>(Arrays.asList(klass.getDeclaredMethods()));
|
||||
for (final Method method : allMethods) {
|
||||
// we filter out methods which aren't annotated @AtlasconversionInfo and have to
|
||||
// also filter out methods which are synthetic methods to avoid duplicates
|
||||
if (method.isAnnotationPresent(AtlasConversionInfo.class) && method.getParameters().length > 0
|
||||
&& !method.isSynthetic()) {
|
||||
String sourceClassName = method.getParameters()[0].getType().getCanonicalName();
|
||||
ConverterKey coordinate = new ConverterKey(sourceClassName,
|
||||
method.getReturnType().getCanonicalName());
|
||||
// if the method has three arguments and the last two as strings then they used
|
||||
// as the format attributes
|
||||
boolean containsFormat = false;
|
||||
if (method.getParameters().length == 3 && method.getParameters()[1].getType() == String.class
|
||||
&& method.getParameters()[2].getType() == String.class) {
|
||||
containsFormat = true;
|
||||
}
|
||||
|
||||
boolean staticMethod = Modifier.isStatic(method.getModifiers());
|
||||
ConverterMethodHolder methodHolder = new ConverterMethodHolder(atlasConverter, method, staticMethod,
|
||||
containsFormat);
|
||||
if (inbuiltConverter) {
|
||||
if (!methodsLoadMap.containsKey(coordinate)) {
|
||||
methodsLoadMap.put(coordinate, methodHolder);
|
||||
} else {
|
||||
LOG.warn("Converter between " + sourceClassName + " and "
|
||||
+ method.getReturnType().getCanonicalName() + " aleady exists.");
|
||||
}
|
||||
} else {
|
||||
if (!customMethodsLoadMap.containsKey(coordinate)) {
|
||||
customMethodsLoadMap.put(coordinate, methodHolder);
|
||||
} else {
|
||||
LOG.warn("Custom converter between " + sourceClassName + " and "
|
||||
+ method.getReturnType().getCanonicalName() + " aleady exists.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// move to the upper class in the hierarchy in search for more methods
|
||||
klass = klass.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object copyPrimitive(Object sourceValue) {
|
||||
|
||||
if (sourceValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<?> clazz = sourceValue.getClass();
|
||||
if (clazz == null) {
|
||||
return clazz;
|
||||
} else if (boolean.class.getName().equals(clazz.getName())) {
|
||||
return Boolean.valueOf((boolean) sourceValue);
|
||||
} else if (Boolean.class.getName().equals(clazz.getName())) {
|
||||
return Boolean.valueOf((Boolean) sourceValue);
|
||||
} else if (byte.class.getName().equals(clazz.getName())) {
|
||||
return Byte.valueOf((byte) sourceValue);
|
||||
} else if (Byte.class.getName().equals(clazz.getName())) {
|
||||
return Byte.valueOf((Byte) sourceValue);
|
||||
} else if (char.class.getName().equals(clazz.getName())) {
|
||||
return Character.valueOf((char) sourceValue);
|
||||
} else if (Character.class.getName().equals(clazz.getName())) {
|
||||
return Character.valueOf((Character) sourceValue);
|
||||
} else if (double.class.getName().equals(clazz.getName())) {
|
||||
return Double.valueOf((double) sourceValue);
|
||||
} else if (Double.class.getName().equals(clazz.getName())) {
|
||||
return Double.valueOf((Double) sourceValue);
|
||||
} else if (float.class.getName().equals(clazz.getName())) {
|
||||
return Float.valueOf((float) sourceValue);
|
||||
} else if (Float.class.getName().equals(clazz.getName())) {
|
||||
return Float.valueOf((Float) sourceValue);
|
||||
} else if (int.class.getName().equals(clazz.getName())) {
|
||||
return Integer.valueOf((int) sourceValue);
|
||||
} else if (Integer.class.getName().equals(clazz.getName())) {
|
||||
return Integer.valueOf((Integer) sourceValue);
|
||||
} else if (long.class.getName().equals(clazz.getName())) {
|
||||
return Long.valueOf((long) sourceValue);
|
||||
} else if (Long.class.getName().equals(clazz.getName())) {
|
||||
return Long.valueOf((Long) sourceValue);
|
||||
} else if (short.class.getName().equals(clazz.getName())) {
|
||||
return Short.valueOf((short) sourceValue);
|
||||
} else if (Short.class.getName().equals(clazz.getName())) {
|
||||
return Short.valueOf((Short) sourceValue);
|
||||
}
|
||||
|
||||
// can't count on java copy
|
||||
return sourceValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertType(Object sourceValue, FieldType origSourceType, FieldType targetType)
|
||||
throws AtlasConversionException {
|
||||
|
||||
if (origSourceType == null || targetType == null) {
|
||||
throw new AtlasConversionException("FieldTypes must be specified on convertType method.");
|
||||
}
|
||||
if (isAssignableFieldType(origSourceType, targetType)) {
|
||||
return sourceValue;
|
||||
}
|
||||
return convertType(sourceValue, null, classFromFieldType(targetType), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertType(Object sourceValue, String sourceFormat, FieldType targetType, String targetFormat)
|
||||
throws AtlasConversionException {
|
||||
return convertType(sourceValue, sourceFormat, classFromFieldType(targetType), targetFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertType(Object sourceValue, String sourceFormat, Class<?> targetType, String targetFormat)
|
||||
throws AtlasConversionException {
|
||||
|
||||
if (sourceValue == null || targetType == null) {
|
||||
throw new AtlasConversionException("AutoConversion requires sourceValue and targetType to be specified");
|
||||
}
|
||||
|
||||
if (targetType.isInstance(sourceValue)) {
|
||||
return sourceValue;
|
||||
}
|
||||
|
||||
ConverterMethodHolder methodHolder = getConverter(sourceValue, targetType);
|
||||
if (methodHolder != null) {
|
||||
try {
|
||||
Object target = methodHolder.staticMethod ? null : methodHolder.converter;
|
||||
if (methodHolder.containsFormat) {
|
||||
return methodHolder.method.invoke(target, sourceValue, sourceFormat, targetFormat);
|
||||
}
|
||||
return methodHolder.method.invoke(target, sourceValue);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new AtlasConversionException("Invoking type convertor failed", e);
|
||||
}
|
||||
}
|
||||
throw new AtlasConversionException("Type Conversion is not supported for sT="
|
||||
+ sourceValue.getClass().getCanonicalName() + " tT=" + targetType.getCanonicalName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConvertionAvailableFor(Object sourceValue, Class<?> targetType) {
|
||||
return targetType.isInstance(sourceValue) || getConverter(sourceValue, targetType) != null;
|
||||
}
|
||||
|
||||
private ConverterMethodHolder getConverter(Object sourceValue, Class<?> targetType) {
|
||||
Class<?> boxedSourceClass = sourceValue.getClass();
|
||||
if (sourceValue.getClass().isPrimitive()) {
|
||||
boxedSourceClass = boxOrUnboxPrimitive(boxedSourceClass);
|
||||
}
|
||||
Class<?> boxedTargetClass = targetType;
|
||||
if (targetType.isPrimitive()) {
|
||||
boxedTargetClass = boxOrUnboxPrimitive(boxedTargetClass);
|
||||
}
|
||||
|
||||
ConverterKey converterKey = new ConverterKey(boxedSourceClass.getCanonicalName(),
|
||||
boxedTargetClass.getCanonicalName());
|
||||
// use custom converter first
|
||||
ConverterMethodHolder methodHolder = customConverterMethods.get(converterKey);
|
||||
if (methodHolder == null) {
|
||||
// try the inbuilt defaults
|
||||
methodHolder = converterMethods.get(converterKey);
|
||||
}
|
||||
return methodHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isPrimitive(String className) {
|
||||
if (className == null) {
|
||||
return false;
|
||||
}
|
||||
if (PRIMITIVE_CLASSNAMES.contains(className)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isPrimitive(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return false;
|
||||
}
|
||||
if (PRIMITIVE_CLASSNAMES.contains(clazz.getCanonicalName())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isPrimitive(FieldType fieldType) {
|
||||
if (fieldType == null) {
|
||||
return false;
|
||||
}
|
||||
return PRIMITIVE_FIELDTYPES.contains(fieldType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isBoxedPrimitive(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return false;
|
||||
}
|
||||
return BOXED_PRIMITIVE_CLASSNAMES.contains(clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> boxOrUnboxPrimitive(String clazzName) {
|
||||
return classFromFieldType(fieldTypeFromClass(clazzName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> boxOrUnboxPrimitive(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return clazz;
|
||||
} else if (boolean.class.getName().equals(clazz.getName())) {
|
||||
return Boolean.class;
|
||||
} else if (Boolean.class.getName().equals(clazz.getName())) {
|
||||
return boolean.class;
|
||||
} else if (byte.class.getName().equals(clazz.getName())) {
|
||||
return Byte.class;
|
||||
} else if (Byte.class.getName().equals(clazz.getName())) {
|
||||
return byte.class;
|
||||
} else if (char.class.getName().equals(clazz.getName())) {
|
||||
return Character.class;
|
||||
} else if (Character.class.getName().equals(clazz.getName())) {
|
||||
return char.class;
|
||||
} else if (double.class.getName().equals(clazz.getName())) {
|
||||
return Double.class;
|
||||
} else if (Double.class.getName().equals(clazz.getName())) {
|
||||
return double.class;
|
||||
} else if (float.class.getName().equals(clazz.getName())) {
|
||||
return Float.class;
|
||||
} else if (Float.class.getName().equals(clazz.getName())) {
|
||||
return float.class;
|
||||
} else if (int.class.getName().equals(clazz.getName())) {
|
||||
return Integer.class;
|
||||
} else if (Integer.class.getName().equals(clazz.getName())) {
|
||||
return int.class;
|
||||
} else if (long.class.getName().equals(clazz.getName())) {
|
||||
return Long.class;
|
||||
} else if (Long.class.getName().equals(clazz.getName())) {
|
||||
return long.class;
|
||||
} else if (short.class.getName().equals(clazz.getName())) {
|
||||
return Short.class;
|
||||
} else if (Short.class.getName().equals(clazz.getName())) {
|
||||
return short.class;
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldType fieldTypeFromClass(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fieldTypeFromClass(clazz.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldType fieldTypeFromClass(String className) {
|
||||
if (className == null || className.isEmpty()) {
|
||||
return FieldType.NONE;
|
||||
}
|
||||
|
||||
switch (className) {
|
||||
case "java.lang.Object":
|
||||
return FieldType.ANY;
|
||||
case "java.math.BigInteger":
|
||||
return FieldType.BIG_INTEGER;
|
||||
case "boolean":
|
||||
case "java.lang.Boolean":
|
||||
return FieldType.BOOLEAN;
|
||||
case "byte":
|
||||
case "java.lang.Byte":
|
||||
return FieldType.BYTE;
|
||||
case "[B":
|
||||
case "[Ljava.lang.Byte":
|
||||
return FieldType.BYTE_ARRAY;
|
||||
case "char":
|
||||
return FieldType.CHAR;
|
||||
case "java.lang.Character":
|
||||
return FieldType.CHAR;
|
||||
case "java.math.BigDecimal":
|
||||
return FieldType.DECIMAL;
|
||||
case "double":
|
||||
case "java.lang.Double":
|
||||
return FieldType.DOUBLE;
|
||||
case "float":
|
||||
case "java.lang.Float":
|
||||
return FieldType.FLOAT;
|
||||
case "int":
|
||||
case "java.lang.Integer":
|
||||
case "java.util.concurrent.atomic.AtomicInteger":
|
||||
return FieldType.INTEGER;
|
||||
case "long":
|
||||
case "java.lang.Long":
|
||||
case "java.util.concurrent.atomic.AtomicLong":
|
||||
return FieldType.LONG;
|
||||
case "java.lang.Number":
|
||||
return FieldType.NUMBER;
|
||||
case "short":
|
||||
case "java.lang.Short":
|
||||
return FieldType.SHORT;
|
||||
case "java.nio.CharBuffer":
|
||||
case "java.lang.CharSequence":
|
||||
case "java.lang.String":
|
||||
case "java.lang.StringBuffer":
|
||||
case "java.lang.StringBuilder":
|
||||
return FieldType.STRING;
|
||||
case "java.sql.Date":
|
||||
case "java.time.LocalDate":
|
||||
case "java.time.Month":
|
||||
case "java.time.MonthDay":
|
||||
case "java.time.Year":
|
||||
case "java.time.YearMonth":
|
||||
return FieldType.DATE;
|
||||
case "java.sql.Time":
|
||||
case "java.time.LocalTime":
|
||||
return FieldType.TIME;
|
||||
case "java.sql.Timestamp":
|
||||
case "java.time.LocalDateTime":
|
||||
case "java.util.Date":
|
||||
return FieldType.DATE_TIME;
|
||||
case "java.time.ZonedDateTime":
|
||||
case "java.util.Calendar":
|
||||
case "java.util.GregorianCalendar":
|
||||
return FieldType.DATE_TIME_TZ;
|
||||
default:
|
||||
return FieldType.COMPLEX;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> classFromFieldType(FieldType fieldType) {
|
||||
if (fieldType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (fieldType) {
|
||||
case ANY:
|
||||
return Object.class;
|
||||
case BIG_INTEGER:
|
||||
return BigInteger.class;
|
||||
case BOOLEAN:
|
||||
return Boolean.class;
|
||||
case BYTE:
|
||||
return Byte.class;
|
||||
case BYTE_ARRAY:
|
||||
return Byte[].class;
|
||||
case CHAR:
|
||||
return java.lang.Character.class;
|
||||
case COMPLEX:
|
||||
// COMPLEX doesn't have representative class
|
||||
return null;
|
||||
case DATE:
|
||||
return java.time.LocalDate.class;
|
||||
case DATE_TIME:
|
||||
return Date.class;
|
||||
case DATE_TZ:
|
||||
case TIME_TZ:
|
||||
case DATE_TIME_TZ:
|
||||
return java.time.ZonedDateTime.class;
|
||||
case DECIMAL:
|
||||
return java.math.BigDecimal.class;
|
||||
case DOUBLE:
|
||||
return java.lang.Double.class;
|
||||
case FLOAT:
|
||||
return java.lang.Float.class;
|
||||
case INTEGER:
|
||||
return java.lang.Integer.class;
|
||||
case LONG:
|
||||
return java.lang.Long.class;
|
||||
case NONE:
|
||||
return null;
|
||||
case NUMBER:
|
||||
return java.lang.Number.class;
|
||||
case SHORT:
|
||||
return java.lang.Short.class;
|
||||
case STRING:
|
||||
return java.lang.String.class;
|
||||
case TIME:
|
||||
return java.time.LocalTime.class;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Unsupported field type '%s': corresponding Java class needs to be added in DefaultAtlasConversionService",
|
||||
fieldType));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isAssignableFieldType(FieldType source, FieldType target) {
|
||||
if (source == null || target == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
if (source.equals(target) || target == FieldType.ANY) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
// Check umbrella field types
|
||||
if (target == FieldType.NUMBER) {
|
||||
return source == FieldType.BIG_INTEGER || source == FieldType.BYTE || source == FieldType.DECIMAL
|
||||
|| source == FieldType.DOUBLE || source == FieldType.FLOAT || source == FieldType.INTEGER
|
||||
|| source == FieldType.LONG || source == FieldType.SHORT;
|
||||
}
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasMappingBuilder;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.CustomMapping;
|
||||
|
||||
public class DefaultAtlasCustomMappingProcessor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasCustomMappingProcessor.class);
|
||||
private static DefaultAtlasCustomMappingProcessor instance;
|
||||
|
||||
public static DefaultAtlasCustomMappingProcessor getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DefaultAtlasCustomMappingProcessor();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void process(DefaultAtlasSession session, CustomMapping customMapping) {
|
||||
String className = customMapping.getClassName();
|
||||
if (className == null || className.isEmpty()) {
|
||||
AtlasUtil.addAudit(session, className,
|
||||
"Custom mapping class must be specified", AuditStatus.ERROR, className);
|
||||
return;
|
||||
}
|
||||
DefaultAtlasContextFactory factory = session.getAtlasContext().getContextFactory();
|
||||
AtlasMappingBuilder builder;
|
||||
try {
|
||||
Class<?> clazz = factory.getClassLoader().loadClass(className);
|
||||
builder = AtlasMappingBuilder.class.cast(clazz.getDeclaredConstructor().newInstance());
|
||||
builder.setAtlasSession(session);
|
||||
} catch (Exception e) {
|
||||
AtlasUtil.addAudit(session, className, String.format(
|
||||
"Custom mapping class '%s' could not be loaded: %s",
|
||||
className, e.getMessage()), AuditStatus.ERROR, className);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error("", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
builder.process();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasConstants;
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.v2.AtlasModelFactory;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.ConstantField;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.PropertyField;
|
||||
import io.atlasmap.v2.SimpleField;
|
||||
|
||||
public class DefaultAtlasExpressionProcessor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasExpressionProcessor.class);
|
||||
|
||||
public static void processExpression(DefaultAtlasSession session, String expression) {
|
||||
if (expression == null || expression.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, Field> sourceFieldMap = new HashMap<>();
|
||||
Field parent = session.head().getSourceField();
|
||||
if (parent != null && !AtlasUtil.isEmpty(parent.getDocId()) && !AtlasUtil.isEmpty(parent.getPath())) {
|
||||
sourceFieldMap.put(parent.getDocId() + ":" + parent.getPath(), parent);
|
||||
}
|
||||
// Anonymous FieldGroup is just a wrapping, peel it off
|
||||
if (parent instanceof FieldGroup && AtlasUtil.isEmpty(parent.getPath())) {
|
||||
FieldGroup parentGroup = FieldGroup.class.cast(parent);
|
||||
for (Field child : parentGroup.getField()) {
|
||||
if (!(AtlasUtil.isEmpty(child.getDocId()) && AtlasUtil.isEmpty(child.getPath()))) {
|
||||
sourceFieldMap.put(child.getDocId() + ":" + child.getPath(), child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expression parsedExpression = Expression.parse(expression, DefaultAtlasFunctionResolver.getInstance());
|
||||
Object answer = parsedExpression.evaluate((path) -> {
|
||||
if (path == null || path.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Field f = sourceFieldMap.get(path);
|
||||
if (f == null) {
|
||||
return null;
|
||||
}
|
||||
AtlasModule sourceModule;
|
||||
Map<String, AtlasModule> sourceModules = session.getAtlasContext().getSourceModules();
|
||||
if (f instanceof ConstantField) {
|
||||
sourceModule = sourceModules.get(AtlasConstants.CONSTANTS_DOCUMENT_ID);
|
||||
} else if (f instanceof PropertyField) {
|
||||
sourceModule = sourceModules.get(AtlasConstants.PROPERTIES_SOURCE_DOCUMENT_ID);
|
||||
} else {
|
||||
String[] splitted = path.split(":", 2);
|
||||
sourceModule = sourceModules.get(splitted[0]);
|
||||
}
|
||||
if (sourceModule == null) {
|
||||
throw new ExpressionException(String.format("Module for the path '%s' is not found", path));
|
||||
}
|
||||
session.head().setSourceField(f);
|
||||
sourceModule.readSourceValue(session);
|
||||
return session.head().getSourceField();
|
||||
} catch (Exception e) {
|
||||
throw new ExpressionException(e);
|
||||
}
|
||||
});
|
||||
if (answer instanceof Field) {
|
||||
session.head().setSourceField((Field)answer);
|
||||
} else {
|
||||
Field from = session.head().getSourceField();
|
||||
SimpleField to = new SimpleField();
|
||||
AtlasModelFactory.copyField(from, to, false);
|
||||
to.setValue(answer);
|
||||
session.head().setSourceField(to);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
AtlasUtil.addAudit(session, expression,
|
||||
String.format("Expression processing error [%s]: %s",
|
||||
expression, e.getMessage()),
|
||||
AuditStatus.ERROR, null);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.FunctionResolver;
|
||||
import io.atlasmap.expression.parser.ParseException;
|
||||
import io.atlasmap.spi.ActionProcessor;
|
||||
import io.atlasmap.spi.FunctionFactory;
|
||||
import io.atlasmap.v2.ActionParameter;
|
||||
import io.atlasmap.v2.ActionParameters;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
|
||||
public class DefaultAtlasFunctionResolver implements FunctionResolver {
|
||||
|
||||
private static DefaultAtlasFunctionResolver instance;
|
||||
|
||||
private HashMap<String, FunctionFactory> functions = new HashMap<>();
|
||||
private DefaultAtlasFieldActionService fieldActionService;
|
||||
|
||||
public static DefaultAtlasFunctionResolver getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DefaultAtlasFunctionResolver();
|
||||
instance.init();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
functions = new HashMap<>();
|
||||
ServiceLoader<FunctionFactory> implementations = ServiceLoader.load(FunctionFactory.class, FunctionFactory.class.getClassLoader());
|
||||
for (FunctionFactory f : implementations) {
|
||||
functions.put(f.getName().toUpperCase(), f);
|
||||
}
|
||||
|
||||
fieldActionService = DefaultAtlasFieldActionService.getInstance();
|
||||
fieldActionService.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression resolve(final String name, List<Expression> args) throws ParseException {
|
||||
String functionName = name.toUpperCase();
|
||||
FunctionFactory f = functions.get(functionName);
|
||||
if (f != null) {
|
||||
return f.create(args);
|
||||
} else {
|
||||
//lookup action
|
||||
return (ctx) -> {
|
||||
List<Field> arguments = new ArrayList<>();
|
||||
for (Expression arg: args) {
|
||||
arguments.add(arg.evaluate(ctx));
|
||||
}
|
||||
|
||||
Object valueForTypeEvaluation = null;
|
||||
if (arguments.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
valueForTypeEvaluation = arguments.get(arguments.size() - 1);
|
||||
}
|
||||
|
||||
ActionProcessor actionProcessor = fieldActionService.findActionProcessor(name, valueForTypeEvaluation);
|
||||
if (actionProcessor != null) {
|
||||
Map<String, Object> actionParameters = new HashMap<>();
|
||||
ActionParameters actionDetailParameters = actionProcessor.getActionDetail().getParameters();
|
||||
if (actionDetailParameters != null && actionDetailParameters.getParameter() != null) {
|
||||
for (ActionParameter parameter : actionDetailParameters.getParameter()) {
|
||||
if (!arguments.isEmpty()) {
|
||||
Object parameterValue = arguments.remove(0).getValue();
|
||||
actionParameters.put(parameter.getName(), parameterValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format("The transformation '%s' expects more parameters. The parameter '%s' is missing", name, parameter.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arguments.isEmpty()) {
|
||||
throw new IllegalArgumentException(String.format("The transformation '%s' expects more arguments", name));
|
||||
}
|
||||
|
||||
FieldGroup fields = new FieldGroup();
|
||||
fields.getField().addAll(arguments);
|
||||
return fieldActionService.buildAndProcessAction(actionProcessor, actionParameters, fields);
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format("The expression function or transformation '%s' was not found", name));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.mxbean.AtlasModuleInfoMXBean;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.AtlasModuleInfo;
|
||||
|
||||
public class DefaultAtlasModuleInfo implements AtlasModuleInfo, AtlasModuleInfoMXBean {
|
||||
private String name;
|
||||
private String uri;
|
||||
private Boolean sourceSupported;
|
||||
private Boolean targetSupported;
|
||||
private Class<AtlasModule> moduleClass;
|
||||
private Constructor<AtlasModule> constructor;
|
||||
private List<String> formats;
|
||||
private List<String> packageNames;
|
||||
|
||||
public DefaultAtlasModuleInfo(String name, String uri, Class<AtlasModule> moduleClass, Constructor<AtlasModule> constructor,
|
||||
List<String> formats, List<String> packageNames) {
|
||||
this.name = name;
|
||||
this.uri = uri;
|
||||
this.moduleClass = moduleClass;
|
||||
this.constructor = constructor;
|
||||
this.formats = formats;
|
||||
this.packageNames = packageNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleClassName() {
|
||||
if (moduleClass != null) {
|
||||
return moduleClass.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Constructor<AtlasModule> getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
public List<String> getFormats() {
|
||||
return formats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<AtlasModule> getModuleClass() {
|
||||
return moduleClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDataFormats() {
|
||||
if (formats != null) {
|
||||
return formats.toArray(new String[formats.size()]);
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPackageNames() {
|
||||
if (packageNames == null || packageNames.size() < 1) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
return packageNames.toArray(new String[packageNames.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSourceSupported() {
|
||||
return sourceSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isTargetSupported() {
|
||||
return targetSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return this.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return this.getClass().getPackage().getImplementationVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DefaultAtlasModuleInfo [name=" + name + ", uri=" + uri + ", sourceSupported=" + sourceSupported
|
||||
+ ", targetSupported=" + targetSupported + ", moduleClass=" + moduleClass + ", constructor="
|
||||
+ constructor + ", formats=" + formats + ", packageNames=" + packageNames + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.spi.AtlasModuleInfo;
|
||||
import io.atlasmap.spi.AtlasModuleInfoRegistry;
|
||||
|
||||
public class DefaultAtlasModuleInfoRegistry implements AtlasModuleInfoRegistry {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasModuleInfoRegistry.class);
|
||||
private final String jmxObjectNamePrefix;
|
||||
private final Set<AtlasModuleInfo> moduleInfos = new HashSet<>();
|
||||
|
||||
public DefaultAtlasModuleInfoRegistry(DefaultAtlasContextFactory factory) {
|
||||
jmxObjectNamePrefix = factory.getJmxObjectName() + ",modules=AvailableModules,moduleName=";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasModuleInfo lookupByUri(String uri) {
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
for (AtlasModuleInfo module : moduleInfos) {
|
||||
if (uri.startsWith(module.getUri())) {
|
||||
return module;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AtlasModuleInfo> getAll() {
|
||||
return Collections.unmodifiableSet(moduleInfos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(AtlasModuleInfo module) {
|
||||
moduleInfos.add(module);
|
||||
registerModuleJmx(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return moduleInfos.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unregisterAll() {
|
||||
for (AtlasModuleInfo info : moduleInfos) {
|
||||
unregisterModuleJmx(info);
|
||||
}
|
||||
moduleInfos.clear();
|
||||
}
|
||||
|
||||
private void registerModuleJmx(AtlasModuleInfo module) {
|
||||
try {
|
||||
String n = jmxObjectNamePrefix + module.getName();
|
||||
ObjectName on = new ObjectName(n);
|
||||
if (!ManagementFactory.getPlatformMBeanServer().isRegistered(on)) {
|
||||
ManagementFactory.getPlatformMBeanServer().registerMBean(module, on);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Registered AtlasModule '" + module.getName() + "' with JMX");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unable to register AtlasModule '" + module.getName() + "' with JMX", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterModuleJmx(AtlasModuleInfo module) {
|
||||
try {
|
||||
String n = jmxObjectNamePrefix + module.getName();
|
||||
ObjectName on = new ObjectName(n);
|
||||
if (ManagementFactory.getPlatformMBeanServer().isRegistered(on)) {
|
||||
ManagementFactory.getPlatformMBeanServer().unregisterMBean(on);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unable to unregister module '" + module.getName() + "' from JMX");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,443 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.api.AtlasPreviewContext;
|
||||
import io.atlasmap.spi.AtlasCollectionHelper;
|
||||
import io.atlasmap.spi.AtlasInternalSession;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.FieldDirection;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.AtlasModelFactory;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.Audits;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.Json;
|
||||
import io.atlasmap.v2.Mapping;
|
||||
import io.atlasmap.v2.MappingType;
|
||||
import io.atlasmap.v2.SimpleField;
|
||||
|
||||
/**
|
||||
* Limited version of AtlasMap context dedicated for preview processing.
|
||||
* Since preview exchanges field values via {@code Field} object, It doesn't interact with
|
||||
* actual {@code AtlasModule} which handles data format specific work, but read the values
|
||||
* from {@code Field} object in the mapping directly.
|
||||
*/
|
||||
class DefaultAtlasPreviewContext extends DefaultAtlasContext implements AtlasPreviewContext {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasPreviewContext.class);
|
||||
|
||||
private Mapping originalMapping;
|
||||
private ObjectMapper jsonMapper;
|
||||
private PreviewModule previewModule = new PreviewModule();
|
||||
private AtlasCollectionHelper collectionHelper;
|
||||
|
||||
|
||||
DefaultAtlasPreviewContext(DefaultAtlasContextFactory factory) {
|
||||
super(factory, new AtlasMapping());
|
||||
this.jsonMapper = Json.withClassLoader(factory.getClassLoader());
|
||||
this.collectionHelper = new DefaultAtlasCollectionHelper(factory.getFieldActionService());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process single mapping entry in preview mode. Since modules don't participate
|
||||
* in preview mode, any document format specific function won't be applied.
|
||||
*
|
||||
* @param mapping A @link{Mapping} entry to process
|
||||
*/
|
||||
@Override
|
||||
public Audits processPreview(Mapping mapping) throws AtlasException {
|
||||
DefaultAtlasSession session = new DefaultAtlasSession(this);
|
||||
this.originalMapping = mapping;
|
||||
Mapping cloned;
|
||||
try {
|
||||
byte[] serialized = jsonMapper.writeValueAsBytes(mapping);
|
||||
cloned = jsonMapper.readValue(serialized, Mapping.class);
|
||||
} catch (Exception e) {
|
||||
throw new AtlasException(e);
|
||||
}
|
||||
session.head().setMapping(cloned);
|
||||
MappingType mappingType = cloned.getMappingType();
|
||||
String expression = cloned.getExpression();
|
||||
FieldGroup sourceFieldGroup = cloned.getInputFieldGroup();
|
||||
List<Field> sourceFields = cloned.getInputField();
|
||||
List<Field> targetFields = cloned.getOutputField();
|
||||
|
||||
targetFields.forEach(tf -> tf.setValue(null));
|
||||
if ((sourceFieldGroup == null && sourceFields.isEmpty()) || targetFields.isEmpty()) {
|
||||
return session.getAudits();
|
||||
}
|
||||
if (sourceFieldGroup != null) {
|
||||
sourceFields = sourceFieldGroup.getField();
|
||||
}
|
||||
for (Field sf : sourceFields) {
|
||||
if (sf.getFieldType() == null || sf.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
if (sf.getValue() instanceof String && ((String)sf.getValue()).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (!restoreSourceFieldType(session, sf)) {
|
||||
return session.getAudits();
|
||||
}
|
||||
}
|
||||
|
||||
processSourceFieldMapping(session);
|
||||
if (session.hasErrors()) {
|
||||
return session.getAudits();
|
||||
}
|
||||
|
||||
Field sourceField = session.head().getSourceField();
|
||||
Field targetField;
|
||||
|
||||
if (mappingType == null || mappingType == MappingType.MAP) {
|
||||
sourceFieldGroup = sourceField instanceof FieldGroup ? (FieldGroup) sourceField : null;
|
||||
for (int i=0; i<targetFields.size(); i++) {
|
||||
targetField = targetFields.get(i);
|
||||
session.head().setTargetField(targetField);
|
||||
if (sourceFieldGroup != null) {
|
||||
if (sourceFieldGroup.getField().size() == 0) {
|
||||
AtlasUtil.addAudit(session, targetField, String.format(
|
||||
"Skipping empty source group field '%s:%s'",
|
||||
sourceField.getDocId(), sourceField.getPath()),
|
||||
AuditStatus.INFO, null);
|
||||
continue;
|
||||
}
|
||||
Integer index = targetField.getIndex();
|
||||
AtlasPath targetPath = new AtlasPath(targetField.getPath());
|
||||
if (targetPath.hasCollection() && !targetPath.isIndexedCollection()) {
|
||||
if (targetFields.size() > 1) {
|
||||
AtlasUtil.addAudit(session, targetField,
|
||||
"It's not yet supported to have a collection field as a part of multiple target fields in a same mapping",
|
||||
AuditStatus.ERROR, null);
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
if (index != null) {
|
||||
LOG.warn("Field index '{}' is detected on target field '{}:{}' while there's only one target field, ignoring",
|
||||
index, targetField.getDocId(), targetField.getPath());
|
||||
targetField.setIndex(null);
|
||||
}
|
||||
FieldGroup targetFieldGroup = targetField instanceof FieldGroup
|
||||
? (FieldGroup)targetField
|
||||
: AtlasModelFactory.createFieldGroupFrom(targetField, true);
|
||||
targetFields.set(i, targetFieldGroup);
|
||||
Field previousTargetField = null;
|
||||
for (Field subSourceField : sourceFieldGroup.getField()) {
|
||||
Field subTargetField = AtlasModelFactory.cloneFieldToSimpleField(targetFieldGroup);
|
||||
targetFieldGroup.getField().add(subTargetField);
|
||||
collectionHelper.copyCollectionIndexes(sourceFieldGroup, subSourceField, subTargetField, previousTargetField);
|
||||
previousTargetField = subTargetField;
|
||||
if (!convertSourceToTarget(session, subSourceField, subTargetField)) {
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
};
|
||||
Field processed = subTargetField;
|
||||
if (expression == null || expression.isEmpty()) {
|
||||
processed = applyFieldActions(session, subTargetField);
|
||||
}
|
||||
subTargetField.setValue(processed.getValue());
|
||||
}
|
||||
continue;
|
||||
} else if (index == null) {
|
||||
session.head().setSourceField(sourceFieldGroup.getField().get(sourceFieldGroup.getField().size()-1));
|
||||
} else {
|
||||
if (sourceFieldGroup.getField().size() > index) {
|
||||
session.head().setSourceField(sourceFieldGroup.getField().get(index));
|
||||
} else {
|
||||
AtlasUtil.addAudit(session, targetField, String.format(
|
||||
"The number of source fields '%s' is fewer than expected via target field index '%s'",
|
||||
sourceFieldGroup.getField().size(), targetField.getIndex()),
|
||||
AuditStatus.WARN, null);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (session.hasErrors()) {
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
if (!convertSourceToTarget(session, session.head().getSourceField(), targetField)) {
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
Field processed = targetField;
|
||||
if (expression == null || expression.isEmpty()) {
|
||||
processed = applyFieldActions(session, targetField);
|
||||
}
|
||||
targetField.setValue(processed.getValue());
|
||||
}
|
||||
|
||||
} else if (mappingType == MappingType.COMBINE) {
|
||||
targetField = targetFields.get(0);
|
||||
Field combined = processCombineField(session, cloned, sourceFields, targetField);
|
||||
if (!convertSourceToTarget(session, combined, targetField)) {
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
applyFieldActions(session, targetField);
|
||||
|
||||
} else if (mappingType == MappingType.SEPARATE) {
|
||||
List<Field> separatedFields;
|
||||
try {
|
||||
separatedFields = processSeparateField(session, cloned, sourceField);
|
||||
} catch (AtlasException e) {
|
||||
AtlasUtil.addAudit(session, sourceField, String.format(
|
||||
"Failed to separate field: %s", AtlasUtil.getChainedMessage(e)),
|
||||
AuditStatus.ERROR, null);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error("", e);
|
||||
}
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
if (separatedFields == null) {
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
for (Field f : targetFields) {
|
||||
targetField = f;
|
||||
if (targetField.getIndex() == null || targetField.getIndex() < 0) {
|
||||
AtlasUtil.addAudit(session, targetField, String.format(
|
||||
"Separate requires zero or positive Index value to be set on targetField targetField.path=%s",
|
||||
targetField.getPath()), AuditStatus.WARN, null);
|
||||
continue;
|
||||
}
|
||||
if (separatedFields.size() <= targetField.getIndex()) {
|
||||
String errorMessage = String.format(
|
||||
"Separate returned fewer segments count=%s when targetField.path=%s requested index=%s",
|
||||
separatedFields.size(), targetField.getPath(), targetField.getIndex());
|
||||
AtlasUtil.addAudit(session, targetField, errorMessage, AuditStatus.WARN, null);
|
||||
break;
|
||||
}
|
||||
if (!convertSourceToTarget(session, separatedFields.get(targetField.getIndex()), targetField)) {
|
||||
break;
|
||||
}
|
||||
applyFieldActions(session, targetField);
|
||||
}
|
||||
|
||||
} else {
|
||||
AtlasUtil.addAudit(session, (String)null, String.format(
|
||||
"Unsupported mappingType=%s detected", cloned.getMappingType()),
|
||||
AuditStatus.ERROR, null);
|
||||
}
|
||||
mapping.getOutputField().clear();
|
||||
mapping.getOutputField().addAll(cloned.getOutputField());
|
||||
session.getAudits().getAudit().addAll(session.head().getAudits());
|
||||
return session.getAudits();
|
||||
}
|
||||
|
||||
private boolean restoreSourceFieldType(DefaultAtlasSession session, Field sourceField) throws AtlasException {
|
||||
try {
|
||||
Object sourceValue = getContextFactory().getConversionService().convertType(
|
||||
sourceField.getValue(), null, sourceField.getFieldType(), null);
|
||||
sourceField.setValue(sourceValue);
|
||||
} catch (AtlasConversionException e) {
|
||||
AtlasUtil.addAudit(session, sourceField, String.format(
|
||||
"Wrong format for source value : %s", AtlasUtil.getChainedMessage(e)),
|
||||
AuditStatus.ERROR, null);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error("", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean convertSourceToTarget(DefaultAtlasSession session, Field sourceField, Field targetField)
|
||||
throws AtlasException {
|
||||
Object targetValue = null;
|
||||
if (sourceField.getFieldType() != null && sourceField.getFieldType().equals(targetField.getFieldType())) {
|
||||
targetValue = sourceField.getValue();
|
||||
} else if (sourceField.getValue() != null) {
|
||||
try {
|
||||
targetValue = getContextFactory().getConversionService().convertType(sourceField.getValue(), sourceField.getFormat(),
|
||||
targetField.getFieldType(), targetField.getFormat());
|
||||
} catch (AtlasConversionException e) {
|
||||
AtlasUtil.addAudit(session, targetField, String.format(
|
||||
"Failed to convert source value to target type: %s", AtlasUtil.getChainedMessage(e)),
|
||||
AuditStatus.ERROR, null);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error("", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
targetField.setValue(targetValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class PreviewModule extends BaseAtlasModule {
|
||||
|
||||
@Override
|
||||
public void readSourceValue(AtlasInternalSession session) throws AtlasException {
|
||||
Field sourceField = session.head().getSourceField();
|
||||
Mapping mapping = session.head().getMapping();
|
||||
FieldGroup sourceFieldGroup = mapping.getInputFieldGroup();
|
||||
if (sourceFieldGroup != null) {
|
||||
if (matches(sourceField, sourceFieldGroup)) {
|
||||
session.head().setSourceField(sourceFieldGroup);
|
||||
return;
|
||||
}
|
||||
Field f = readFromGroup(sourceFieldGroup, sourceField);
|
||||
session.head().setSourceField(f);
|
||||
return;
|
||||
}
|
||||
for (Field f : mapping.getInputField()) {
|
||||
if (matches(sourceField, f)) {
|
||||
session.head().setSourceField(f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matches(Field f1, Field f2) {
|
||||
if ((f1.getDocId() == null && f2.getDocId() != null)
|
||||
|| (f1.getDocId() != null && f2.getDocId() == null)
|
||||
|| (f1.getDocId() != null && !f1.getDocId().equals(f2.getDocId()))) {
|
||||
return false;
|
||||
}
|
||||
if (f2.getPath() != null && f2.getPath().equals(f1.getPath())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Field readFromGroup(FieldGroup group, Field field) {
|
||||
if (group.getField() == null) {
|
||||
return null;
|
||||
}
|
||||
for (Field f : group.getField()) {
|
||||
if (matches(field, f)) {
|
||||
return f;
|
||||
}
|
||||
if (f instanceof FieldGroup) {
|
||||
Field deeper = readFromGroup((FieldGroup)f, field);
|
||||
if (deeper != null) {
|
||||
return deeper;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSupportedField(Field field) {
|
||||
// The field type doesn't matter for preview
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreValidation(AtlasInternalSession session) throws AtlasException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreSourceExecution(AtlasInternalSession session) throws AtlasException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreTargetExecution(AtlasInternalSession session) throws AtlasException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTargetValue(AtlasInternalSession session) throws AtlasException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostSourceExecution(AtlasInternalSession session) throws AtlasException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostTargetExecution(AtlasInternalSession session) throws AtlasException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field cloneField(Field field) throws AtlasException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocName() {
|
||||
return "Preview";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocId() {
|
||||
return "Preview";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleField createField() {
|
||||
return new SimpleField();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
public Map<String, AtlasModule> getSourceModules() {
|
||||
return new HashMap<String, AtlasModule>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public AtlasModule get(Object key) {
|
||||
return previewModule;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AtlasModule resolveModule(FieldDirection direction, Field field) {
|
||||
return previewModule;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasConversionException;
|
||||
import io.atlasmap.api.AtlasSession;
|
||||
import io.atlasmap.api.AtlasUnsupportedException;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasPropertyStrategy;
|
||||
import io.atlasmap.spi.AtlasPropertyType;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.AtlasModelFactory;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
import io.atlasmap.v2.Property;
|
||||
import io.atlasmap.v2.PropertyField;
|
||||
|
||||
public class DefaultAtlasPropertyStrategy implements AtlasPropertyStrategy {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultAtlasPropertyStrategy.class);
|
||||
|
||||
private boolean environmentPropertiesEnabled = true;
|
||||
private boolean systemPropertiesEnabled = true;
|
||||
private boolean mappingDefinedPropertiesEnabled = true;
|
||||
private boolean runtimePropertiesEnabled = true;
|
||||
|
||||
private List<AtlasPropertyType> propertyOrder = Arrays.asList(
|
||||
AtlasPropertyType.RUNTIME_PROPERTIES,
|
||||
AtlasPropertyType.JAVA_SYSTEM_PROPERTIES,
|
||||
AtlasPropertyType.ENVIRONMENT_VARIABLES,
|
||||
AtlasPropertyType.MAPPING_DEFINED_PROPERTIES);
|
||||
|
||||
private AtlasConversionService atlasConversionService = null;
|
||||
|
||||
@Override
|
||||
public void readProperty(AtlasSession session, PropertyField propertyField)
|
||||
throws AtlasUnsupportedException, AtlasConversionException {
|
||||
if (propertyField == null || propertyField.getName() == null || propertyField.getName().trim().length() == 0) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Null or empty PropertyField specified popertyField=%s",
|
||||
AtlasModelFactory.toString(propertyField)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (AtlasPropertyType propType : getPropertyOrder()) {
|
||||
switch (propType) {
|
||||
case RUNTIME_PROPERTIES:
|
||||
if (session != null && processRuntimeProperties(propertyField, session.getSourceProperties())) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case JAVA_SYSTEM_PROPERTIES:
|
||||
if (processJavaSystemProperty(propertyField)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case ENVIRONMENT_VARIABLES:
|
||||
if (processEnvironmentVariable(propertyField)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MAPPING_DEFINED_PROPERTIES:
|
||||
if (session != null && processMappingDefinedProperties(propertyField, session.getMapping())) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new AtlasUnsupportedException(
|
||||
String.format("Unsupported PropertyType detected type=%s for field=%s", propType,
|
||||
AtlasModelFactory.toString(propertyField)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean processEnvironmentVariable(PropertyField propertyField)
|
||||
throws AtlasConversionException {
|
||||
|
||||
if (!isEnvironmentPropertiesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (System.getenv(propertyField.getName()) != null) {
|
||||
Object propertyValue = System.getenv(propertyField.getName());
|
||||
if (getAtlasConversionService() != null && propertyField.getFieldType() != null) {
|
||||
propertyField.setValue(getAtlasConversionService().convertType(propertyValue,
|
||||
null, atlasConversionService.classFromFieldType(propertyField.getFieldType()), null));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Assigned environment variable property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
} else {
|
||||
propertyField.setValue(propertyValue);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Assigned environment variable for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
LOG.error(String.format("SecurityException while processing environment variable for propertyField=%s",
|
||||
AtlasModelFactory.toString(propertyField)), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean processJavaSystemProperty(PropertyField propertyField)
|
||||
throws AtlasConversionException {
|
||||
|
||||
if (!isSystemPropertiesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (System.getProperty(propertyField.getName()) != null) {
|
||||
Object propertyValue = System.getProperty(propertyField.getName());
|
||||
if (getAtlasConversionService() != null && propertyField.getFieldType() != null) {
|
||||
propertyField.setValue(getAtlasConversionService().convertType(propertyValue,
|
||||
null, atlasConversionService.classFromFieldType(propertyField.getFieldType()), null));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Assigned Java system property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
} else {
|
||||
propertyField.setValue(propertyValue);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Assigned Java system property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
LOG.error(String.format("SecurityException while processing Java system property for propertyField=%s",
|
||||
AtlasModelFactory.toString(propertyField)), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean processMappingDefinedProperties(PropertyField propertyField, AtlasMapping atlasMapping)
|
||||
throws AtlasConversionException {
|
||||
|
||||
if (!isMappingDefinedPropertiesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (atlasMapping == null || atlasMapping.getProperties() == null
|
||||
|| atlasMapping.getProperties().getProperty() == null
|
||||
|| atlasMapping.getProperties().getProperty().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Property prop : atlasMapping.getProperties().getProperty()) {
|
||||
if (propertyField.getName().equals(prop.getName())) {
|
||||
if (getAtlasConversionService() != null
|
||||
&& (propertyField.getFieldType() != null || prop.getFieldType() != null)) {
|
||||
propertyField.setValue(getAtlasConversionService().convertType(prop.getValue(), FieldType.STRING,
|
||||
(propertyField.getFieldType() != null ? propertyField.getFieldType()
|
||||
: prop.getFieldType())));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(
|
||||
String.format("Assigned Mapping defined property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
} else {
|
||||
propertyField.setValue(prop.getValue());
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(
|
||||
String.format("Assigned Mapping defined property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean processRuntimeProperties(PropertyField propertyField, Map<String, Object> runtimeProperties)
|
||||
throws AtlasConversionException {
|
||||
|
||||
if (!isRuntimePropertiesEnabled() || runtimeProperties == null || runtimeProperties.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String key = propertyField.getName();
|
||||
if (key == null || key.isEmpty() || !runtimeProperties.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getAtlasConversionService() != null && propertyField.getFieldType() != null) {
|
||||
propertyField.setValue(getAtlasConversionService().convertType(runtimeProperties.get(key),
|
||||
null, atlasConversionService.classFromFieldType(propertyField.getFieldType()), null));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Assigned Runtime defined property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
} else {
|
||||
propertyField.setValue(runtimeProperties.get(key));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Assigned Runtime defined property for property field name=%s value=%s",
|
||||
propertyField.getName(), propertyField.getValue()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeProperty(AtlasSession session, PropertyField propertyField) {
|
||||
if (propertyField == null || propertyField.getName() == null || propertyField.getName().trim().length() == 0) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Null or empty PropertyField specified popertyField=%s",
|
||||
AtlasModelFactory.toString(propertyField)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
session.getTargetProperties().put(propertyField.getName(), propertyField.getValue());
|
||||
}
|
||||
|
||||
public void setPropertyOrderValue(List<String> propertyValues) {
|
||||
List<AtlasPropertyType> tmp = null;
|
||||
|
||||
for (String v : propertyValues) {
|
||||
if (tmp == null) {
|
||||
tmp = new LinkedList<AtlasPropertyType>();
|
||||
}
|
||||
|
||||
try {
|
||||
tmp.add(AtlasPropertyType.fromValue(v));
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.error(String.format("Invalid AtlasPropertyType specified '%s'", v));
|
||||
}
|
||||
}
|
||||
|
||||
propertyOrder = null;
|
||||
propertyOrder = tmp;
|
||||
}
|
||||
|
||||
public boolean isEnvironmentPropertiesEnabled() {
|
||||
return environmentPropertiesEnabled;
|
||||
}
|
||||
|
||||
public void setEnvironmentPropertiesEnabled(boolean environmentPropertiesEnabled) {
|
||||
this.environmentPropertiesEnabled = environmentPropertiesEnabled;
|
||||
}
|
||||
|
||||
public boolean isSystemPropertiesEnabled() {
|
||||
return systemPropertiesEnabled;
|
||||
}
|
||||
|
||||
public void setSystemPropertiesEnabled(boolean systemPropertiesEnabled) {
|
||||
this.systemPropertiesEnabled = systemPropertiesEnabled;
|
||||
}
|
||||
|
||||
public boolean isMappingDefinedPropertiesEnabled() {
|
||||
return mappingDefinedPropertiesEnabled;
|
||||
}
|
||||
|
||||
public void setMappingDefinedPropertiesEnabled(boolean mappingDefinedPropertiesEnabled) {
|
||||
this.mappingDefinedPropertiesEnabled = mappingDefinedPropertiesEnabled;
|
||||
}
|
||||
|
||||
public boolean isRuntimePropertiesEnabled() {
|
||||
return runtimePropertiesEnabled;
|
||||
}
|
||||
|
||||
public void setRuntimePropertiesEnabled(boolean runtimePropertiesEnabled) {
|
||||
this.runtimePropertiesEnabled = runtimePropertiesEnabled;
|
||||
}
|
||||
|
||||
public List<AtlasPropertyType> getPropertyOrder() {
|
||||
return propertyOrder;
|
||||
}
|
||||
|
||||
public void setPropertyOrder(List<AtlasPropertyType> propertyOrder) {
|
||||
this.propertyOrder = propertyOrder;
|
||||
}
|
||||
|
||||
public AtlasConversionService getAtlasConversionService() {
|
||||
return atlasConversionService;
|
||||
}
|
||||
|
||||
public void setAtlasConversionService(AtlasConversionService atlasConversionService) {
|
||||
this.atlasConversionService = atlasConversionService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.spi.AtlasSeparateStrategy;
|
||||
import io.atlasmap.spi.StringDelimiter;
|
||||
|
||||
public class DefaultAtlasSeparateStrategy implements AtlasSeparateStrategy {
|
||||
|
||||
public static final Integer DEFAULT_SEPARATE_LIMIT = new Integer(512);
|
||||
public static final StringDelimiter DEFAULT_SEPARATE_DELIMITER = StringDelimiter.MULTI_SPACE;
|
||||
|
||||
private StringDelimiter delimiter = DEFAULT_SEPARATE_DELIMITER;
|
||||
private Integer limit = DEFAULT_SEPARATE_LIMIT;
|
||||
|
||||
@Override
|
||||
public StringDelimiter getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDelimiter(StringDelimiter delimiter) {
|
||||
this.delimiter = delimiter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLimit(Integer limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> separateValue(String value) {
|
||||
return separateValue(value, getDelimiter(), getLimit());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> separateValue(String value, StringDelimiter delimiter) {
|
||||
return separateValue(value, delimiter, getLimit());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> separateValue(String value, StringDelimiter delimiter, Integer limit) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
if (value == null || value.isEmpty()) {
|
||||
return values;
|
||||
}
|
||||
|
||||
values.addAll(Arrays.asList(value.split((delimiter == null ? DEFAULT_SEPARATE_DELIMITER.getRegex() : delimiter.getRegex()),
|
||||
(limit == null ? DEFAULT_SEPARATE_LIMIT : limit))));
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import io.atlasmap.api.AtlasConstants;
|
||||
import io.atlasmap.api.AtlasContext;
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.spi.AtlasFieldReader;
|
||||
import io.atlasmap.spi.AtlasFieldWriter;
|
||||
import io.atlasmap.spi.AtlasInternalSession;
|
||||
import io.atlasmap.spi.AtlasModule;
|
||||
import io.atlasmap.spi.AtlasPropertyStrategy;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.Audit;
|
||||
import io.atlasmap.v2.AuditStatus;
|
||||
import io.atlasmap.v2.Audits;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.LookupTable;
|
||||
import io.atlasmap.v2.Mapping;
|
||||
import io.atlasmap.v2.Validations;
|
||||
|
||||
public class DefaultAtlasSession implements AtlasInternalSession {
|
||||
|
||||
private DefaultAtlasContext atlasContext;
|
||||
private final AtlasMapping mapping;
|
||||
private Audits audits;
|
||||
private Validations validations;
|
||||
private Map<String, Object> sourceProperties;
|
||||
private Map<String, Object> targetProperties;
|
||||
private AtlasPropertyStrategy propertyStrategy;
|
||||
private Map<String, Object> sourceMap;
|
||||
private Map<String, Object> targetMap;
|
||||
private Map<String, AtlasFieldReader> fieldReaderMap;
|
||||
private Map<String, AtlasFieldWriter> fieldWriterMap;
|
||||
private Head head = new HeadImpl(this);
|
||||
private String defaultSourceDocumentId;
|
||||
private String defaultTargetDocumentId;
|
||||
|
||||
public DefaultAtlasSession(DefaultAtlasContext context) throws AtlasException {
|
||||
this.atlasContext = context;
|
||||
initialize();
|
||||
if (context.getMapping() == null) {
|
||||
this.mapping = null;
|
||||
return;
|
||||
}
|
||||
this.mapping = context.getADMArchiveHandler().cloneMappingDefinition();
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
sourceProperties = new ConcurrentHashMap<String, Object>();
|
||||
targetProperties = new ConcurrentHashMap<String, Object>();
|
||||
validations = new Validations();
|
||||
audits = new Audits();
|
||||
sourceMap = new HashMap<>();
|
||||
targetMap = new HashMap<>();
|
||||
fieldReaderMap = new HashMap<>();
|
||||
fieldWriterMap = new HashMap<>();
|
||||
head.unset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultAtlasContext getAtlasContext() {
|
||||
return atlasContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAtlasContext(AtlasContext atlasContext) {
|
||||
this.atlasContext = (DefaultAtlasContext) atlasContext;
|
||||
head.unset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasMapping getMapping() {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Validations getValidations() {
|
||||
return this.validations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValidations(Validations validations) {
|
||||
this.validations = validations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Audits getAudits() {
|
||||
return this.audits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudits(Audits audits) {
|
||||
this.audits = audits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultSourceDocument() {
|
||||
return sourceMap.get(getDefaultSourceDocumentId());
|
||||
}
|
||||
|
||||
private String getDefaultSourceDocumentId() {
|
||||
if (this.defaultSourceDocumentId == null) {
|
||||
Optional<String> found = this.atlasContext.getSourceModules().keySet().stream().filter((key) ->
|
||||
!AtlasConstants.CONSTANTS_DOCUMENT_ID.equals(key)
|
||||
&& !AtlasConstants.PROPERTIES_SOURCE_DOCUMENT_ID.equals(key))
|
||||
.findFirst();
|
||||
this.defaultSourceDocumentId = found.isPresent() ? found.get() : AtlasConstants.DEFAULT_SOURCE_DOCUMENT_ID;
|
||||
}
|
||||
return this.defaultSourceDocumentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSourceDocument(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return getDefaultSourceDocument();
|
||||
}
|
||||
if (sourceMap.containsKey(docId)) {
|
||||
return sourceMap.get(docId);
|
||||
} else if (sourceMap.size() == 1 && sourceMap.containsKey(AtlasConstants.DEFAULT_SOURCE_DOCUMENT_ID)) {
|
||||
AtlasUtil.addAudit(this, docId, String.format(
|
||||
"There's no source document with docId='%s', returning default", docId),
|
||||
AuditStatus.WARN, null);
|
||||
return getDefaultSourceDocument();
|
||||
}
|
||||
AtlasUtil.addAudit(this, docId, String.format(
|
||||
"There's no source document with docId='%s'", docId), AuditStatus.WARN, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSourceDocument(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return sourceMap.containsKey(AtlasConstants.DEFAULT_SOURCE_DOCUMENT_ID);
|
||||
}
|
||||
return sourceMap.containsKey(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSourceDocumentMap() {
|
||||
return Collections.unmodifiableMap(sourceMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultTargetDocument() {
|
||||
return targetMap.get(getDefaultTargetDocumentId());
|
||||
}
|
||||
|
||||
private String getDefaultTargetDocumentId() {
|
||||
if (this.defaultTargetDocumentId == null) {
|
||||
Optional<String> found = this.atlasContext.getTargetModules().keySet().stream().filter((key) ->
|
||||
!AtlasConstants.PROPERTIES_TARGET_DOCUMENT_ID.equals(key))
|
||||
.findFirst();
|
||||
this.defaultTargetDocumentId = found.isPresent() ? found.get() : AtlasConstants.DEFAULT_TARGET_DOCUMENT_ID;
|
||||
}
|
||||
return this.defaultTargetDocumentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTargetDocument(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return getDefaultTargetDocument();
|
||||
}
|
||||
if (targetMap.containsKey(docId)) {
|
||||
return targetMap.get(docId);
|
||||
} else if (targetMap.size() == 1 && targetMap.containsKey(AtlasConstants.DEFAULT_TARGET_DOCUMENT_ID)) {
|
||||
AtlasUtil.addAudit(this, docId, String.format(
|
||||
"There's no target document with docId='%s', returning default", docId),
|
||||
AuditStatus.WARN, null);
|
||||
return getDefaultTargetDocument();
|
||||
}
|
||||
AtlasUtil.addAudit(this, docId, String.format(
|
||||
"There's no target document with docId='%s'", docId), AuditStatus.WARN, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTargetDocument(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return targetMap.containsKey(AtlasConstants.DEFAULT_TARGET_DOCUMENT_ID);
|
||||
}
|
||||
return targetMap.containsKey(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTargetDocumentMap() {
|
||||
return Collections.unmodifiableMap(targetMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultSourceDocument(Object sourceDoc) {
|
||||
this.sourceMap.put(getDefaultSourceDocumentId(), sourceDoc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceDocument(String docId, Object sourceDoc) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
setDefaultSourceDocument(sourceDoc);
|
||||
} else {
|
||||
// first document is mapped to 'default' as well
|
||||
if (this.sourceMap.isEmpty()) {
|
||||
setDefaultSourceDocument(sourceDoc);
|
||||
}
|
||||
this.sourceMap.put(docId, sourceDoc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultTargetDocument(Object targetDoc) {
|
||||
this.targetMap.put(getDefaultTargetDocumentId(), targetDoc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDocument(String docId, Object targetDoc) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
setDefaultTargetDocument(targetDoc);
|
||||
} else {
|
||||
// first document is mapped to 'default' as well
|
||||
if (this.targetMap.isEmpty()) {
|
||||
setDefaultTargetDocument(targetDoc);
|
||||
}
|
||||
this.targetMap.put(docId, targetDoc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasFieldReader getFieldReader(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return this.fieldReaderMap.get(AtlasConstants.DEFAULT_SOURCE_DOCUMENT_ID);
|
||||
}
|
||||
return this.fieldReaderMap.get(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends AtlasFieldReader> T getFieldReader(String docId, Class<T> clazz) {
|
||||
return clazz.cast(getFieldReader(docId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFieldReader(String docId, AtlasFieldReader reader) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
this.fieldReaderMap.put(AtlasConstants.DEFAULT_SOURCE_DOCUMENT_ID, reader);
|
||||
} else {
|
||||
this.fieldReaderMap.put(docId, reader);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasFieldReader removeFieldReader(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return this.fieldReaderMap.remove(AtlasConstants.DEFAULT_SOURCE_DOCUMENT_ID);
|
||||
}
|
||||
return fieldReaderMap.remove(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasFieldWriter getFieldWriter(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return this.fieldWriterMap.get(AtlasConstants.DEFAULT_TARGET_DOCUMENT_ID);
|
||||
}
|
||||
return this.fieldWriterMap.get(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends AtlasFieldWriter> T getFieldWriter(String docId, Class<T> clazz) {
|
||||
return clazz.cast(getFieldWriter(docId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFieldWriter(String docId, AtlasFieldWriter writer) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
this.fieldWriterMap.put(AtlasConstants.DEFAULT_TARGET_DOCUMENT_ID, writer);
|
||||
}
|
||||
this.fieldWriterMap.put(docId, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasFieldWriter removeFieldWriter(String docId) {
|
||||
if (docId == null || docId.isEmpty()) {
|
||||
return this.fieldWriterMap.remove(AtlasConstants.DEFAULT_TARGET_DOCUMENT_ID);
|
||||
}
|
||||
return this.fieldWriterMap.remove(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head head() {
|
||||
return this.head;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Map<String, Object> getProperties() {
|
||||
return getSourceProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSourceProperties() {
|
||||
return this.sourceProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTargetProperties() {
|
||||
return this.targetProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasPropertyStrategy getAtlasPropertyStrategy() {
|
||||
return this.propertyStrategy;
|
||||
}
|
||||
@Override
|
||||
public void setAtlasPropertyStrategy(AtlasPropertyStrategy strategy) {
|
||||
this.propertyStrategy = strategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer errorCount() {
|
||||
int e = 0;
|
||||
for (Audit audit : getAudits().getAudit()) {
|
||||
if (AuditStatus.ERROR.equals(audit.getStatus())) {
|
||||
e++;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasErrors() {
|
||||
for (Audit audit : getAudits().getAudit()) {
|
||||
if (AuditStatus.ERROR.equals(audit.getStatus())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWarns() {
|
||||
for (Audit audit : getAudits().getAudit()) {
|
||||
if (AuditStatus.WARN.equals(audit.getStatus())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer warnCount() {
|
||||
int w = 0;
|
||||
for (Audit audit : getAudits().getAudit()) {
|
||||
if (AuditStatus.WARN.equals(audit.getStatus())) {
|
||||
w++;
|
||||
}
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasModule resolveModule(String docId) {
|
||||
// Assuming Document ID is unique across source and target
|
||||
AtlasModule answer = this.getAtlasContext().getSourceModules().get(docId);
|
||||
if (answer == null) {
|
||||
answer = this.getAtlasContext().getTargetModules().get(docId);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public ConstantModule getConstantModule() {
|
||||
return (ConstantModule) this.getAtlasContext().getSourceModules().get(AtlasConstants.CONSTANTS_DOCUMENT_ID);
|
||||
}
|
||||
|
||||
public PropertyModule getSourcePropertyModule() {
|
||||
return (PropertyModule) this.getAtlasContext().getSourceModules().get(AtlasConstants.PROPERTIES_SOURCE_DOCUMENT_ID);
|
||||
}
|
||||
|
||||
public PropertyModule getTargetPropertyModule() {
|
||||
return (PropertyModule) this.getAtlasContext().getTargetModules().get(AtlasConstants.PROPERTIES_TARGET_DOCUMENT_ID);
|
||||
}
|
||||
|
||||
private class HeadImpl implements Head {
|
||||
private DefaultAtlasSession session;
|
||||
private Mapping mapping;
|
||||
private LookupTable lookupTable;
|
||||
private Field sourceField;
|
||||
private Field targetField;
|
||||
private List<Audit> audits = new LinkedList<Audit>();
|
||||
|
||||
public HeadImpl(DefaultAtlasSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mapping getMapping() {
|
||||
return this.mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookupTable getLookupTable() {
|
||||
return this.lookupTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field getSourceField() {
|
||||
return this.sourceField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field getTargetField() {
|
||||
return this.targetField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head setMapping(Mapping mapping) {
|
||||
this.mapping = mapping;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head setLookupTable(LookupTable table) {
|
||||
this.lookupTable = table;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head setSourceField(Field sourceField) {
|
||||
this.sourceField = sourceField;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head setTargetField(Field targetField) {
|
||||
this.targetField = targetField;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head unset() {
|
||||
this.mapping = null;
|
||||
this.lookupTable = null;
|
||||
this.sourceField = null;
|
||||
this.targetField = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasError() {
|
||||
for(Audit audit : audits) {
|
||||
if (audit.getStatus() == AuditStatus.ERROR) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Head addAudit(AuditStatus status, Field field, String message) {
|
||||
String docId = field != null ? field.getDocId() : null;
|
||||
String docName = AtlasUtil.getDocumentNameById(session, docId);
|
||||
String path = field != null ? field.getPath() : null;
|
||||
Audit audit = AtlasUtil.createAudit(status, docId, docName, path, null, message);
|
||||
this.audits.add(audit);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Audit> getAudits() {
|
||||
return this.audits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.atlasmap.api.AtlasValidationService;
|
||||
import io.atlasmap.spi.AtlasValidator;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.BaseMapping;
|
||||
import io.atlasmap.v2.DataSource;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.LookupTable;
|
||||
import io.atlasmap.v2.LookupTables;
|
||||
import io.atlasmap.v2.Mapping;
|
||||
import io.atlasmap.v2.MappingType;
|
||||
import io.atlasmap.v2.Mappings;
|
||||
import io.atlasmap.v2.Validation;
|
||||
import io.atlasmap.v2.ValidationScope;
|
||||
import io.atlasmap.v2.ValidationStatus;
|
||||
import io.atlasmap.validators.CompositeValidator;
|
||||
import io.atlasmap.validators.LookupTableNameValidator;
|
||||
import io.atlasmap.validators.NonNullValidator;
|
||||
import io.atlasmap.validators.NotEmptyValidator;
|
||||
import io.atlasmap.validators.PositiveIntegerValidator;
|
||||
import io.atlasmap.validators.StringPatternValidator;
|
||||
|
||||
public class DefaultAtlasValidationService implements AtlasValidationService {
|
||||
|
||||
enum Validators {
|
||||
MAPPING_NAME (() -> {
|
||||
StringPatternValidator namePattern = new StringPatternValidator(
|
||||
ValidationScope.ALL,
|
||||
"Mapping name must not contain spaces nor special characters other than period (.) and underscore (_), but was '%s'",
|
||||
"[^A-Za-z0-9_.]");
|
||||
NonNullValidator nameNotNull = new NonNullValidator(
|
||||
ValidationScope.ALL, "Mapping name must not be null nor empty");
|
||||
return new CompositeValidator(namePattern, nameNotNull);
|
||||
}),
|
||||
DATASOURCE_TARGET_URI (() ->
|
||||
new NonNullValidator(ValidationScope.DATA_SOURCE, "DataSource target uri must not be null nor empty")
|
||||
),
|
||||
DATASOURCE_SOURCE_URI (() ->
|
||||
new NonNullValidator(ValidationScope.DATA_SOURCE, "DataSource source uri must not be null nor empty")
|
||||
),
|
||||
|
||||
MAPPINGS_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Field mappings must not be null")
|
||||
),
|
||||
|
||||
COMBINE_INPUT_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Source field should not be null")
|
||||
),
|
||||
COMBINE_INPUT_FIELD_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Source field should not be empty")
|
||||
),
|
||||
COMBINE_OUTPUT_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Target element must not be null")
|
||||
),
|
||||
COMBINE_OUTPUT_FIELD_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Target field must not be empty")
|
||||
),
|
||||
COMBINE_INPUT_FIELD_NOT_NULL (() ->
|
||||
new NonNullValidator(
|
||||
ValidationScope.MAPPING, "Source fields should not be null")
|
||||
),
|
||||
COMBINE_INPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE (() ->
|
||||
new PositiveIntegerValidator(
|
||||
ValidationScope.MAPPING, "MapAction index must exists and be greater than or equal to zero (0), but was '%s'")
|
||||
),
|
||||
|
||||
MAP_INPUT_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Source field must not be null")
|
||||
),
|
||||
MAP_INPUT_FIELD_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Source field must not be empty")
|
||||
),
|
||||
MAP_OUTPUT_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Target field should not be null")
|
||||
),
|
||||
MAP_OUTPUT_FIELD_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Target field should not be empty")
|
||||
),
|
||||
|
||||
SEPARATE_INPUT_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Source field must not be null")
|
||||
),
|
||||
SEPARATE_INPUT_FIELD_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Source field must not be null")
|
||||
),
|
||||
SEPARATE_INPUT_FIELD_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Source field must not be empty")
|
||||
),
|
||||
SEPARATE_OUTPUT_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Target field should not be null")
|
||||
),
|
||||
SEPARATE_OUTPUT_FIELD_NOT_NULL (() ->
|
||||
new NonNullValidator(ValidationScope.MAPPING, "Target fields should not be null")
|
||||
),
|
||||
SEPARATE_OUTPUT_FIELD_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Target fields should not be empty")
|
||||
),
|
||||
SEPARATE_OUTPUT_FIELD_FIELD_ACTION_NOT_EMPTY (() ->
|
||||
new NotEmptyValidator(ValidationScope.MAPPING, "Field actions cannot be null or empty")
|
||||
),
|
||||
SEPARATE_OUTPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE (() ->
|
||||
new PositiveIntegerValidator(ValidationScope.MAPPING, "MapAction index must exists and be greater than or equal to zero (0), but was '%s'")
|
||||
),
|
||||
|
||||
LOOKUPTABLE_NAME_CHECK_FOR_DUPLICATE (() ->
|
||||
new LookupTableNameValidator("LookupTables contain duplicated LookupTable names '%s'.")
|
||||
);
|
||||
|
||||
private final AtlasValidator validator;
|
||||
private Validators(Supplier<AtlasValidator> s) {
|
||||
validator = s.get();
|
||||
}
|
||||
|
||||
public AtlasValidator get() {
|
||||
return validator;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Validation> validateMapping(AtlasMapping mapping) {
|
||||
if (mapping == null) {
|
||||
throw new IllegalArgumentException("Mapping definition must not be null");
|
||||
}
|
||||
List<Validation> validations = new ArrayList<>();
|
||||
Validators.MAPPING_NAME.get().validate(mapping.getName(), validations, null);
|
||||
|
||||
List<DataSource> dataSources = mapping.getDataSource();
|
||||
for (DataSource ds : dataSources) {
|
||||
switch (ds.getDataSourceType()) {
|
||||
case SOURCE:
|
||||
Validators.DATASOURCE_SOURCE_URI.get().validate(ds.getUri(), validations, ds.getId());
|
||||
break;
|
||||
case TARGET:
|
||||
Validators.DATASOURCE_TARGET_URI.get().validate(ds.getUri(), validations, ds.getId());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(String.format("Unknown DataSource type '%s'", ds.getDataSourceType()));
|
||||
}
|
||||
}
|
||||
validateFieldMappings(mapping.getMappings(), mapping.getLookupTables(), validations);
|
||||
return validations;
|
||||
}
|
||||
|
||||
private void validateFieldMappings(Mappings mappings, LookupTables lookupTables, List<Validation> validations) {
|
||||
Validators.MAPPINGS_NOT_NULL.get().validate(mappings, validations, null);
|
||||
if (mappings != null) {
|
||||
List<BaseMapping> fieldMappings = mappings.getMapping();
|
||||
if (fieldMappings != null && !fieldMappings.isEmpty()) {
|
||||
List<Mapping> mapFieldMappings = fieldMappings.stream()
|
||||
.filter(p -> p.getMappingType() == MappingType.MAP).map(p -> (Mapping) p)
|
||||
.collect(Collectors.toList());
|
||||
List<Mapping> combineFieldMappings = fieldMappings.stream()
|
||||
.filter(p -> p.getMappingType() == MappingType.COMBINE).map(p -> (Mapping) p)
|
||||
.collect(Collectors.toList());
|
||||
List<Mapping> separateFieldMappings = fieldMappings.stream()
|
||||
.filter(p -> p.getMappingType() == MappingType.SEPARATE).map(p -> (Mapping) p)
|
||||
.collect(Collectors.toList());
|
||||
List<Mapping> lookupFieldMappings = fieldMappings.stream()
|
||||
.filter(p -> p.getMappingType() == MappingType.LOOKUP).map(p -> (Mapping) p)
|
||||
.collect(Collectors.toList());
|
||||
Set<String> usedIds = new HashSet<>();
|
||||
validateMapMapping(mapFieldMappings, validations, usedIds);
|
||||
validateCombineMapping(combineFieldMappings, validations, usedIds);
|
||||
validateSeparateMapping(separateFieldMappings, validations, usedIds);
|
||||
validateLookupTables(lookupFieldMappings, lookupTables, validations, usedIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateLookupTables(List<Mapping> lookupFieldMappings, LookupTables lookupTables,
|
||||
List<Validation> validations, Set<String> usedIds) {
|
||||
if (lookupTables != null && lookupTables.getLookupTable() != null && !lookupTables.getLookupTable().isEmpty()) {
|
||||
// check for duplicate names
|
||||
Validators.LOOKUPTABLE_NAME_CHECK_FOR_DUPLICATE.get().validate(lookupTables, validations, null);
|
||||
if (lookupFieldMappings.isEmpty()) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.LOOKUP_TABLE);
|
||||
validation.setMessage("LookupTables are defined but no LookupFields are utilized.");
|
||||
validation.setStatus(ValidationStatus.WARN);
|
||||
validations.add(validation);
|
||||
} else {
|
||||
validateLookupFieldMapping(lookupFieldMappings, lookupTables, validations, usedIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mapping field validations
|
||||
private void validateLookupFieldMapping(List<Mapping> fieldMappings, LookupTables lookupTables,
|
||||
List<Validation> validations, Set<String> usedIds) {
|
||||
Set<String> lookupFieldMappingTableNameRefs = fieldMappings.stream().map(Mapping::getLookupTableName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Set<String> tableNames = lookupTables.getLookupTable().stream().map(LookupTable::getName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (!lookupFieldMappingTableNameRefs.isEmpty() && !tableNames.isEmpty()) {
|
||||
Set<String> disjoint = Stream.concat(lookupFieldMappingTableNameRefs.stream(), tableNames.stream())
|
||||
.collect(Collectors.toMap(Function.identity(), t -> true, (a, b) -> null)).keySet();
|
||||
if (!disjoint.isEmpty()) {
|
||||
|
||||
boolean isInFieldList = !lookupFieldMappingTableNameRefs.stream().filter(disjoint::contains)
|
||||
.collect(Collectors.toList()).isEmpty();
|
||||
boolean isInTableNameList = !tableNames.stream().filter(disjoint::contains).collect(Collectors.toList())
|
||||
.isEmpty();
|
||||
// which list has the disjoin.... if its the lookup fields then ERROR
|
||||
if (isInFieldList) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.LOOKUP_TABLE);
|
||||
validation.setMessage(
|
||||
"One ore more LookupFieldMapping references a non existent LookupTable name in the mapping: " + disjoint.toString());
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
|
||||
// check that if a name exists in table names that at least one field mapping
|
||||
// uses it, else WARN
|
||||
if (isInTableNameList) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.LOOKUP_TABLE);
|
||||
validation.setMessage("A LookupTable is defined but not used by any LookupField: " + disjoint.toString());
|
||||
validation.setStatus(ValidationStatus.WARN);
|
||||
validations.add(validation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Mapping fieldMapping : fieldMappings) {
|
||||
String mappingId = fieldMapping.getId();
|
||||
validateMappingId(mappingId, usedIds, validations);
|
||||
if (fieldMapping.getInputField() != null) {
|
||||
Validators.MAP_INPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getInputField(), validations, mappingId);
|
||||
}
|
||||
Validators.MAP_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
if (fieldMapping.getOutputField() != null) {
|
||||
Validators.MAP_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void validateMapMapping(List<Mapping> fieldMappings, List<Validation> validations, Set<String> usedIds) {
|
||||
for (Mapping fieldMapping : fieldMappings) {
|
||||
String mappingId = fieldMapping.getId();
|
||||
FieldGroup sourceFieldGroup = fieldMapping.getInputFieldGroup();
|
||||
List<Field> sourceFields = sourceFieldGroup != null ? sourceFieldGroup.getField() : fieldMapping.getInputField();
|
||||
validateMappingId(mappingId, usedIds, validations);
|
||||
Validators.MAP_INPUT_NOT_NULL.get().validate(sourceFields, validations, mappingId);
|
||||
if (fieldMapping.getInputField() != null) {
|
||||
Validators.MAP_INPUT_FIELD_NOT_EMPTY.get().validate(sourceFields, validations, mappingId);
|
||||
}
|
||||
Validators.MAP_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
if (fieldMapping.getOutputField() != null) {
|
||||
Validators.MAP_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSeparateMapping(List<Mapping> fieldMappings, List<Validation> validations, Set<String> usedIds) {
|
||||
for (Mapping fieldMapping : fieldMappings) {
|
||||
String mappingId = fieldMapping.getId();
|
||||
validateMappingId(mappingId, usedIds, validations);
|
||||
Validators.SEPARATE_INPUT_NOT_NULL.get().validate(fieldMapping.getInputField(), validations, mappingId);
|
||||
if (fieldMapping.getInputField() != null) {
|
||||
Validators.SEPARATE_INPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getInputField(), validations, mappingId);
|
||||
// source must be a String type
|
||||
}
|
||||
|
||||
Validators.SEPARATE_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
Validators.SEPARATE_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
|
||||
if (fieldMapping.getOutputField() != null) {
|
||||
for (Field field : fieldMapping.getOutputField()) {
|
||||
Validators.SEPARATE_OUTPUT_FIELD_NOT_NULL.get().validate(field, validations, mappingId);
|
||||
if (field.getIndex() == null || field.getIndex() < 0) {
|
||||
Validators.SEPARATE_OUTPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE.get().validate(field.getIndex(),
|
||||
validations, mappingId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateCombineMapping(List<Mapping> fieldMappings, List<Validation> validations, Set<String> usedIds) {
|
||||
for (Mapping fieldMapping : fieldMappings) {
|
||||
String mappingId = fieldMapping.getId();
|
||||
validateMappingId(mappingId, usedIds, validations);
|
||||
Validators.COMBINE_OUTPUT_NOT_NULL.get().validate(fieldMapping.getOutputField(), validations, mappingId);
|
||||
if (fieldMapping.getOutputField() != null) {
|
||||
Validators.COMBINE_OUTPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getOutputField(), validations, mappingId);
|
||||
// source must be a String type
|
||||
}
|
||||
|
||||
Validators.COMBINE_INPUT_NOT_NULL.get().validate(fieldMapping.getInputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
Validators.COMBINE_INPUT_FIELD_NOT_EMPTY.get().validate(fieldMapping.getInputField(), validations,
|
||||
mappingId, ValidationStatus.WARN);
|
||||
|
||||
if (fieldMapping.getInputField() != null) {
|
||||
for (Field field : fieldMapping.getInputField()) {
|
||||
Validators.COMBINE_INPUT_FIELD_NOT_NULL.get().validate(field, validations, mappingId);
|
||||
if (field.getIndex() == null || field.getIndex() < 0) {
|
||||
Validators.COMBINE_INPUT_FIELD_FIELD_ACTION_INDEX_POSITIVE.get().validate(field.getIndex(),
|
||||
validations, mappingId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateMappingId(String id, Set<String> usedIds, List<Validation> validations) {
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
if (usedIds.contains(id)) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setMessage(String.format("Duplicated mapping ID '%s' is found", id));
|
||||
validation.setStatus(ValidationStatus.WARN);
|
||||
validations.add(validation);
|
||||
} else {
|
||||
usedIds.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.spi.AtlasInternalSession;
|
||||
import io.atlasmap.spi.AtlasPropertyStrategy;
|
||||
import io.atlasmap.v2.AtlasModelFactory;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.PropertyField;
|
||||
|
||||
public class PropertyModule extends BaseAtlasModule {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PropertyModule.class);
|
||||
|
||||
private AtlasPropertyStrategy defaultStrategy;
|
||||
|
||||
public PropertyModule(AtlasPropertyStrategy propertyStrategy) {
|
||||
this.defaultStrategy = propertyStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreValidation(AtlasInternalSession session) throws AtlasException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreSourceExecution(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSourceValue(AtlasInternalSession session) throws AtlasException {
|
||||
AtlasPropertyStrategy strategy = session.getAtlasPropertyStrategy() != null
|
||||
? session.getAtlasPropertyStrategy() : this.defaultStrategy;
|
||||
Field sourceField = session.head().getSourceField();
|
||||
if (sourceField instanceof PropertyField) {
|
||||
PropertyField sourcePropertyField = (PropertyField)sourceField;
|
||||
strategy.readProperty(session, sourcePropertyField);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Processed source PropertyField: Name={} Scope={} Value={} Strategy={}",
|
||||
sourcePropertyField.getName(), sourcePropertyField.getScope(),
|
||||
sourceField.getValue(), strategy.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostSourceExecution(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPreTargetExecution(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTargetValue(AtlasInternalSession session) throws AtlasException {
|
||||
AtlasPropertyStrategy strategy = session.getAtlasPropertyStrategy() != null
|
||||
? session.getAtlasPropertyStrategy() : this.defaultStrategy;
|
||||
Field targetField = session.head().getTargetField();
|
||||
if (targetField instanceof PropertyField) {
|
||||
PropertyField targetPropertyField = (PropertyField)targetField;
|
||||
strategy.writeProperty(session, targetPropertyField);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Processed target PropertyField: Name={} Value={} Strategy={}",
|
||||
targetPropertyField.getName(), targetPropertyField.getValue(),
|
||||
strategy.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostTargetExecution(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPostValidation(AtlasInternalSession session) throws AtlasException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSupportedField(Field field) {
|
||||
return field instanceof PropertyField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyField cloneField(Field field) throws AtlasException {
|
||||
if (field == null || !(field instanceof PropertyField)) {
|
||||
return null;
|
||||
}
|
||||
PropertyField orig = (PropertyField)field;
|
||||
PropertyField clone = new PropertyField();
|
||||
AtlasModelFactory.copyField(orig, clone, true);
|
||||
clone.setScope(orig.getScope());
|
||||
return clone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocName(String docName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocName() {
|
||||
return "Properties";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyField createField() {
|
||||
return new PropertyField();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A template-based combine strategy that uses a template in place of a delimiter to combine the input using
|
||||
* {@link MessageFormat#format(String, Object...)}.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> The indexes in the template must be one-based, unlike the
|
||||
* {@link MessageFormat#format(String, Object...)} method, which expects zero-based indexes.
|
||||
* </p>
|
||||
*/
|
||||
public class TemplateCombineStrategy extends DefaultAtlasCombineStrategy {
|
||||
|
||||
@Override
|
||||
public String combineValues(Map<Integer, String> values, String template) {
|
||||
if (values == null || values.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Default to default combine with default delimiter if template is missing
|
||||
if (template == null || template.isEmpty()) {
|
||||
return combineValues(values);
|
||||
}
|
||||
|
||||
StringBuilder templateBuilder = new StringBuilder();
|
||||
|
||||
// Convert indexes in template to zero-based (since specified by user as one-based)
|
||||
StringCharacterIterator iter = new StringCharacterIterator(template);
|
||||
boolean escaped = false;
|
||||
for (char chr = iter.first(); chr != StringCharacterIterator.DONE; chr = iter.next()) {
|
||||
templateBuilder.append(chr);
|
||||
if (chr == '\'' && !escaped) {
|
||||
escaped = true;
|
||||
} else {
|
||||
if (chr == '{' && !escaped) {
|
||||
StringBuilder indexBuilder = new StringBuilder();
|
||||
for (chr = iter.next(); Character.isDigit(chr); chr = iter.next()) {
|
||||
indexBuilder.append(chr);
|
||||
}
|
||||
templateBuilder.append(Integer.valueOf(indexBuilder.toString()) - 1);
|
||||
templateBuilder.append(chr);
|
||||
}
|
||||
escaped = false;
|
||||
}
|
||||
}
|
||||
|
||||
values = DefaultAtlasCombineStrategy.sortByKey(values);
|
||||
return MessageFormat.format(templateBuilder.toString(), values.values().toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core;
|
||||
|
||||
public class ValidationConstants {
|
||||
|
||||
public static final String DATASOURCE_URI_NOT_NULL = "DataSourceURINotNull";
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core.validate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.api.AtlasValidationService;
|
||||
import io.atlasmap.core.DefaultAtlasCollectionHelper;
|
||||
import io.atlasmap.core.DefaultAtlasConversionService;
|
||||
import io.atlasmap.core.DefaultAtlasFieldActionService;
|
||||
import io.atlasmap.spi.AtlasConversionService;
|
||||
import io.atlasmap.spi.AtlasFieldActionService;
|
||||
import io.atlasmap.spi.AtlasModuleDetail;
|
||||
import io.atlasmap.spi.AtlasModuleMode;
|
||||
import io.atlasmap.spi.FieldDirection;
|
||||
import io.atlasmap.v2.AtlasMapping;
|
||||
import io.atlasmap.v2.BaseMapping;
|
||||
import io.atlasmap.v2.CustomMapping;
|
||||
import io.atlasmap.v2.DataSource;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
import io.atlasmap.v2.Mapping;
|
||||
import io.atlasmap.v2.MappingType;
|
||||
import io.atlasmap.v2.Validation;
|
||||
import io.atlasmap.v2.ValidationScope;
|
||||
import io.atlasmap.v2.ValidationStatus;
|
||||
|
||||
public abstract class BaseModuleValidationService<T extends Field> implements AtlasValidationService {
|
||||
|
||||
private AtlasConversionService conversionService;
|
||||
private AtlasFieldActionService fieldActionService;
|
||||
private DefaultAtlasCollectionHelper collectionHelper;
|
||||
private AtlasModuleMode mode;
|
||||
private String docId;
|
||||
private MappingFieldPairValidator mappingFieldPairValidator;
|
||||
|
||||
public BaseModuleValidationService() {
|
||||
this.conversionService = DefaultAtlasConversionService.getInstance();
|
||||
this.fieldActionService = DefaultAtlasFieldActionService.getInstance();
|
||||
this.collectionHelper = new DefaultAtlasCollectionHelper(this.fieldActionService);
|
||||
init();
|
||||
}
|
||||
|
||||
public BaseModuleValidationService(AtlasConversionService conversionService, AtlasFieldActionService fieldActionService) {
|
||||
this.conversionService = conversionService;
|
||||
this.fieldActionService = fieldActionService;
|
||||
this.collectionHelper = new DefaultAtlasCollectionHelper(fieldActionService);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.mappingFieldPairValidator = new MappingFieldPairValidator(this);
|
||||
}
|
||||
|
||||
public void setMode(AtlasModuleMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public AtlasModuleMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void setDocId(String docId) {
|
||||
this.docId = docId;
|
||||
}
|
||||
|
||||
public String getDocId() {
|
||||
return this.docId;
|
||||
}
|
||||
|
||||
protected abstract AtlasModuleDetail getModuleDetail();
|
||||
|
||||
@Override
|
||||
public List<Validation> validateMapping(AtlasMapping mapping) {
|
||||
List<Validation> validations = new ArrayList<>();
|
||||
if (getMode() == AtlasModuleMode.UNSET) {
|
||||
Validation validation = new Validation();
|
||||
validation.setMessage(String.format(
|
||||
"No mode specified for %s/%s, skipping module validations",
|
||||
this.getModuleDetail().name(), this.getClass().getSimpleName()));
|
||||
}
|
||||
|
||||
if (mapping != null && mapping.getMappings() != null && mapping.getMappings().getMapping() != null
|
||||
&& !mapping.getMappings().getMapping().isEmpty()) {
|
||||
validateMappingEntries(mapping.getMappings().getMapping(), validations);
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (DataSource ds : mapping.getDataSource()) {
|
||||
if (ds.getUri() != null && ds.getUri().startsWith(getModuleDetail().uri())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.DATA_SOURCE);
|
||||
validation.setMessage(String.format("No DataSource with '%s' uri specified", getModuleDetail().uri()));
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
|
||||
return validations;
|
||||
}
|
||||
|
||||
protected void validateMappingEntries(List<BaseMapping> mappings, List<Validation> validations) {
|
||||
for (BaseMapping fieldMapping : mappings) {
|
||||
if (fieldMapping.getClass().isAssignableFrom(CustomMapping.class)) {
|
||||
validateCustomMapping((CustomMapping)fieldMapping, validations);
|
||||
} else if (fieldMapping.getClass().isAssignableFrom(Mapping.class)
|
||||
&& MappingType.SEPARATE.equals(((Mapping) fieldMapping).getMappingType())) {
|
||||
validateSeparateMapping((Mapping) fieldMapping, validations);
|
||||
} else if (fieldMapping.getClass().isAssignableFrom(Mapping.class)
|
||||
&& MappingType.COMBINE.equals(((Mapping) fieldMapping).getMappingType())) {
|
||||
validateCombineMapping((Mapping) fieldMapping, validations);
|
||||
} else {
|
||||
if (fieldMapping instanceof io.atlasmap.v2.Collection) {
|
||||
fieldMapping = ((io.atlasmap.v2.Collection)fieldMapping).getMappings().getMapping().get(0);
|
||||
}
|
||||
validateMapMapping((Mapping) fieldMapping, validations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateMapMapping(Mapping mapping, List<Validation> validations) {
|
||||
if (mapping == null
|
||||
|| mapping.getInputField() == null || (mapping.getInputFieldGroup() == null && mapping.getInputField().size() <= 0)
|
||||
|| mapping.getOutputField() == null || mapping.getOutputField().size() <= 0) {
|
||||
return;
|
||||
}
|
||||
String mappingId = mapping.getId();
|
||||
|
||||
if (getMode() == AtlasModuleMode.SOURCE) {
|
||||
FieldGroup sourceFieldGroup = mapping.getInputFieldGroup();
|
||||
if (sourceFieldGroup != null) {
|
||||
validateFieldGroup(mappingId, sourceFieldGroup, FieldDirection.SOURCE, validations);
|
||||
} else {
|
||||
List<Field> sourceFields = mapping.getInputField();
|
||||
sourceFields.forEach(sourceField -> {
|
||||
validateField(mappingId, null, sourceField, FieldDirection.SOURCE, validations);
|
||||
});
|
||||
}
|
||||
} else if (getMode() == AtlasModuleMode.TARGET) {
|
||||
List<Field> targetFields = mapping.getOutputField();
|
||||
|
||||
if (targetFields.size() == 1 && Integer.valueOf(0).equals(targetFields.get(0).getIndex())) {
|
||||
//The index should not have been set as there's only one item
|
||||
targetFields.get(0).setIndex(null);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
List<Field> sourceFields = mapping.getInputField();
|
||||
for (Field targetField: targetFields) {
|
||||
if (sourceFields.size() > i) {
|
||||
validateField(mappingId, sourceFields.get(i), targetField, FieldDirection.TARGET, validations);
|
||||
} else {
|
||||
validateField(mappingId, null, targetField, FieldDirection.TARGET, validations);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (getMode() == AtlasModuleMode.SOURCE) {
|
||||
validateFieldCombinations(mapping, validations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateCustomMapping(CustomMapping mapping, List<Validation> validations) {
|
||||
if (mapping.getClassName() == null || mapping.getClassName().isEmpty()) {
|
||||
Validation v = new Validation();
|
||||
v.setScope(ValidationScope.MAPPING);
|
||||
v.setMessage("Class name must be specified for custom mapping");
|
||||
v.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(v);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateFieldGroup(String mappingId, FieldGroup fieldGroup, FieldDirection direction, List<Validation> validations) {
|
||||
fieldGroup.getField().forEach(f -> {validateField(mappingId, null, f, direction, validations);});
|
||||
}
|
||||
|
||||
protected void validateFieldCombinations(Mapping mapping, List<Validation> validations) {
|
||||
String mappingId = mapping.getId();
|
||||
FieldGroup sourceFieldGroup = mapping.getInputFieldGroup();
|
||||
List<Field> sourceFields = mapping.getInputField();
|
||||
List<Field> targetFields = mapping.getOutputField();
|
||||
if (sourceFieldGroup != null || (sourceFields != null && sourceFields.size() > 1)) {
|
||||
if (targetFields.size() > 1) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage("Multiple fields can not be selected on both of Source and Target");
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
if (sourceFieldGroup != null) {
|
||||
mappingFieldPairValidator.validateFieldTypes(validations, mappingId, sourceFieldGroup, targetFields.get(0));
|
||||
} else {
|
||||
mappingFieldPairValidator.validateFieldTypes(validations, mappingId, sourceFields, targetFields.get(0));
|
||||
}
|
||||
} else if (targetFields != null && targetFields.size() > 1) {
|
||||
mappingFieldPairValidator.validateFieldTypes(validations, mappingId, sourceFields.get(0), targetFields);
|
||||
} else {
|
||||
mappingFieldPairValidator.validateFieldTypes(validations, mappingId, sourceFields.get(0), targetFields.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void validateField(String mappingId, Field sourceField, Field targetField, FieldDirection direction, List<Validation> validations) {
|
||||
if (targetField == null) {
|
||||
return;
|
||||
}
|
||||
if (direction == FieldDirection.TARGET) {
|
||||
Integer sourceCollectionCount = null;
|
||||
if (sourceField != null) {
|
||||
sourceCollectionCount = collectionHelper.determineSourceCollectionCount(null, sourceField);
|
||||
}
|
||||
|
||||
Integer targetCollectionCount = collectionHelper.determineTargetCollectionCount(targetField);
|
||||
|
||||
if (sourceCollectionCount != null) {
|
||||
if (sourceCollectionCount > targetCollectionCount) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
String message = String.format(
|
||||
"Target [%s] has %s collection(s) on the path, whereas source has %s. Values from the %s rightmost " +
|
||||
"source collections on the path will be added in depth-first order to the rightmost target " +
|
||||
"collection(s) unless transformed explicitly.",
|
||||
targetField.getPath(), targetCollectionCount, sourceCollectionCount,
|
||||
sourceCollectionCount - targetCollectionCount + 1);
|
||||
validation.setMessage(message);
|
||||
validation.setStatus(ValidationStatus.WARN);
|
||||
validations.add(validation);
|
||||
} else if (sourceCollectionCount < targetCollectionCount) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(String.format("The 0 index will be used for any extra parent collections in " +
|
||||
"target [%s], since target has %s collections on the path, whereas source has %s.",
|
||||
targetField.getPath(), targetCollectionCount, sourceCollectionCount));
|
||||
validation.setStatus(ValidationStatus.WARN);
|
||||
validations.add(validation);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (getFieldType().isAssignableFrom(targetField.getClass()) && matchDocIdOrNull(targetField.getDocId())) {
|
||||
validateModuleField(mappingId, (T)targetField, direction, validations);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Class<T> getFieldType();
|
||||
|
||||
protected abstract void validateModuleField(String mappingId, T field, FieldDirection direction, List<Validation> validation);
|
||||
|
||||
protected boolean matchDocIdOrNull(String docId) {
|
||||
return docId == null || getDocId().equals(docId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected String getFieldName(Field field) {
|
||||
if (field == null) {
|
||||
return "null";
|
||||
}
|
||||
if (field.getClass().isAssignableFrom(getFieldType())) {
|
||||
return getModuleFieldName((T)field);
|
||||
}
|
||||
if (field.getFieldType() != null) {
|
||||
return field.getFieldType().name();
|
||||
}
|
||||
return field.getClass().getName();
|
||||
}
|
||||
|
||||
protected abstract String getModuleFieldName(T field);
|
||||
|
||||
protected AtlasConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
protected AtlasFieldActionService getFieldActionService() {
|
||||
return fieldActionService;
|
||||
}
|
||||
|
||||
protected MappingFieldPairValidator getMappingFieldPairValidator() {
|
||||
return mappingFieldPairValidator;
|
||||
}
|
||||
|
||||
protected void setMappingFieldPairValidator(MappingFieldPairValidator mfpv) {
|
||||
mappingFieldPairValidator = mfpv;
|
||||
}
|
||||
|
||||
protected void setConversionService(AtlasConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
/*
|
||||
* vvv Remove in 2.0 vvv
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
protected void validateCombineMapping(Mapping mapping, List<Validation> validations) {
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Field> sourceFields = mapping.getInputField();
|
||||
|
||||
final List<Field> targetFields = mapping.getOutputField();
|
||||
final Field targetField = (targetFields != null && !targetFields.isEmpty()) ? targetFields.get(0) : null;
|
||||
if (targetField == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String mappingId = mapping.getId();
|
||||
|
||||
if (getMode() == AtlasModuleMode.TARGET && matchDocIdOrNull(targetField.getDocId())) {
|
||||
if (sourceFields != null) {
|
||||
// FIXME Run only for TARGET to avoid duplicate validation...
|
||||
// we should convert per module validations to plugin style
|
||||
for (Field sourceField : sourceFields) {
|
||||
mappingFieldPairValidator.validateFieldTypes(validations, mappingId, sourceField, targetField);
|
||||
}
|
||||
}
|
||||
|
||||
// check that the output field is of type String else error
|
||||
if (targetField.getFieldType() != null && targetField.getFieldType() != FieldType.STRING) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(String.format(
|
||||
"Target field '%s' must be of type '%s' for a Combine Mapping",
|
||||
getFieldName(targetField), FieldType.STRING));
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
validateField(mappingId, null, targetField, FieldDirection.TARGET, validations);
|
||||
} else if (sourceFields != null) { // SOURCE
|
||||
for (Field sourceField : sourceFields) {
|
||||
if (matchDocIdOrNull(sourceField.getDocId())) {
|
||||
validateField(mappingId, null, sourceField, FieldDirection.SOURCE, validations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected void validateSeparateMapping(Mapping mapping, List<Validation> validations) {
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Field> sourceFields = mapping.getInputField();
|
||||
final Field sourceField = (sourceFields != null && !sourceFields.isEmpty()) ? sourceFields.get(0) : null;
|
||||
if (sourceField == null) {
|
||||
return;
|
||||
}
|
||||
List<Field> targetFields = mapping.getOutputField();
|
||||
String mappingId = mapping.getId();
|
||||
|
||||
if (getMode() == AtlasModuleMode.SOURCE && matchDocIdOrNull(sourceField.getDocId())) {
|
||||
// check that the source field is of type String else error
|
||||
if (sourceField.getFieldType() != null && sourceField.getFieldType() != FieldType.STRING) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mapping.getId());
|
||||
validation.setMessage(String.format(
|
||||
"Source field '%s' must be of type '%s' for a Separate Mapping",
|
||||
getFieldName(sourceField), FieldType.STRING));
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
validateField(mappingId, null, sourceField, FieldDirection.SOURCE, validations);
|
||||
|
||||
if (targetFields != null) {
|
||||
// FIXME Run only for SOURCE to avoid duplicate validation...
|
||||
// we should convert per module validations to plugin style
|
||||
for (Field targetField : targetFields) {
|
||||
mappingFieldPairValidator.validateFieldTypes(validations, mappingId, sourceField, targetField);
|
||||
}
|
||||
}
|
||||
} else if (targetFields != null) { // TARGET
|
||||
for (Field targetField : targetFields) {
|
||||
if (matchDocIdOrNull(targetField.getDocId())) {
|
||||
validateField(mappingId, null, targetField, FieldDirection.TARGET, validations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core.validate;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.atlasmap.api.AtlasException;
|
||||
import io.atlasmap.spi.AtlasConversionConcern;
|
||||
import io.atlasmap.spi.AtlasConversionInfo;
|
||||
import io.atlasmap.spi.AtlasConverter;
|
||||
import io.atlasmap.v2.Action;
|
||||
import io.atlasmap.v2.ActionDetail;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.FieldGroup;
|
||||
import io.atlasmap.v2.FieldType;
|
||||
import io.atlasmap.v2.Validation;
|
||||
import io.atlasmap.v2.ValidationScope;
|
||||
import io.atlasmap.v2.ValidationStatus;
|
||||
|
||||
public class MappingFieldPairValidator {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MappingFieldPairValidator.class);
|
||||
|
||||
private BaseModuleValidationService<?> service;
|
||||
|
||||
public MappingFieldPairValidator(BaseModuleValidationService<?> service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void validateFieldTypes(List<Validation> validations, String mappingId, FieldGroup sourceFieldGroup, Field targetField) {
|
||||
FieldType actionOutputType = getActionOutputFieldType(validations, mappingId, sourceFieldGroup);
|
||||
for (Field sourceField : sourceFieldGroup.getField()) {
|
||||
if (!service.matchDocIdOrNull(sourceField.getDocId())) {
|
||||
return;
|
||||
}
|
||||
doValidateFieldTypes(validations, mappingId, sourceField, targetField,
|
||||
actionOutputType != null ? actionOutputType : sourceField.getFieldType());
|
||||
}
|
||||
}
|
||||
|
||||
public void validateFieldTypes(List<Validation> validations, String mappingId, List<Field> sourceFields, Field targetField) {
|
||||
for (Field sourceField : sourceFields) {
|
||||
if (!service.matchDocIdOrNull(sourceField.getDocId())) {
|
||||
return;
|
||||
}
|
||||
FieldType actionOutputType = getActionOutputFieldType(validations, mappingId, sourceField);
|
||||
doValidateFieldTypes(validations, mappingId, sourceField, targetField,
|
||||
actionOutputType != null ? actionOutputType : sourceField.getFieldType());
|
||||
}
|
||||
}
|
||||
|
||||
public void validateFieldTypes(List<Validation> validations, String mappingId, Field sourceField, List<Field> targetFields) {
|
||||
if (!service.matchDocIdOrNull(sourceField.getDocId())) {
|
||||
return;
|
||||
}
|
||||
FieldType actionOutputType = getActionOutputFieldType(validations, mappingId, sourceField);
|
||||
for (Field targetField : targetFields) {
|
||||
doValidateFieldTypes(validations, mappingId, sourceField, targetField,
|
||||
actionOutputType != null ? actionOutputType : sourceField.getFieldType());
|
||||
}
|
||||
}
|
||||
|
||||
public void validateFieldTypes(List<Validation> validations, String mappingId, Field sourceField, Field targetField) {
|
||||
FieldType actionOutputType = getActionOutputFieldType(validations, mappingId, sourceField);
|
||||
doValidateFieldTypes(validations, mappingId, sourceField, targetField,
|
||||
actionOutputType != null ? actionOutputType : sourceField.getFieldType());
|
||||
}
|
||||
|
||||
protected void doValidateFieldTypes(List<Validation> validations, String mappingId, Field sourceField, Field targetField, FieldType sourceFieldType) {
|
||||
if (sourceField == null && targetField == null || sourceField.getFieldType() == targetField.getFieldType()) {
|
||||
return;
|
||||
}
|
||||
FieldType targetFieldType = targetField.getFieldType();
|
||||
if (sourceFieldType == null || targetFieldType == null) {
|
||||
return;
|
||||
}
|
||||
if (sourceFieldType == FieldType.ANY || targetFieldType == FieldType.ANY) {
|
||||
return;
|
||||
}
|
||||
// skip converter check for COMPLEX source field (possible for conditional mapping)
|
||||
if (sourceField.getFieldType() == FieldType.COMPLEX) {
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<AtlasConverter<?>> atlasConverter = service.getConversionService().findMatchingConverter(sourceFieldType, targetFieldType);
|
||||
if (!atlasConverter.isPresent()) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(String.format(
|
||||
"Conversion from '%s' to '%s' is required but no converter is available",
|
||||
sourceField.getFieldType(), targetField.getFieldType()));
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
} else {
|
||||
AtlasConversionInfo conversionInfo;
|
||||
// find the method that does the conversion
|
||||
FieldType sft = sourceFieldType;
|
||||
Method[] methods = atlasConverter.get().getClass().getMethods();
|
||||
conversionInfo = Arrays.stream(methods).map(method -> method.getAnnotation(AtlasConversionInfo.class))
|
||||
.filter(atlasConversionInfo -> atlasConversionInfo != null)
|
||||
.filter(atlasConversionInfo -> (atlasConversionInfo.sourceType().compareTo(sft) == 0
|
||||
&& atlasConversionInfo.targetType().compareTo(targetFieldType) == 0))
|
||||
.findFirst().orElse(null);
|
||||
if (conversionInfo != null) {
|
||||
populateConversionConcerns(validations, mappingId, conversionInfo, service.getFieldName(sourceField), service.getFieldName(targetField));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FieldType getActionOutputFieldType(List<Validation> validations, String mappingId, Field f) {
|
||||
if (f.getActions() == null || f.getActions().size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Action lastAction = f.getActions().get(f.getActions().size()-1);
|
||||
ActionDetail detail = null;
|
||||
try {
|
||||
detail = service.getFieldActionService().findActionDetail(lastAction, f.getFieldType());
|
||||
} catch (AtlasException e) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error("ActionDetail not found", e);
|
||||
}
|
||||
}
|
||||
if (detail == null) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(String.format(
|
||||
"Couldn't find a metadata for transformation '%s'", lastAction.getDisplayName()));
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
return null;
|
||||
}
|
||||
return detail.getTargetType();
|
||||
}
|
||||
|
||||
public void populateConversionConcerns(List<Validation> validations, String mappingId, AtlasConversionInfo converterAnno,
|
||||
String sourceFieldName, String targetFieldName) {
|
||||
if (converterAnno == null || converterAnno.concerns() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (AtlasConversionConcern atlasConversionConcern : converterAnno.concerns()) {
|
||||
String message = atlasConversionConcern.getMessage(converterAnno);
|
||||
if (AtlasConversionConcern.NONE.equals(atlasConversionConcern)) {
|
||||
continue; // just supported - even INFO is verbose
|
||||
} else if (atlasConversionConcern.equals(AtlasConversionConcern.RANGE)
|
||||
|| atlasConversionConcern.equals(AtlasConversionConcern.FORMAT)
|
||||
|| atlasConversionConcern.equals(AtlasConversionConcern.FRACTIONAL_PART)
|
||||
|| atlasConversionConcern.equals(AtlasConversionConcern.TIMEZONE)) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(message);
|
||||
validation.setStatus(ValidationStatus.WARN);
|
||||
validations.add(validation);
|
||||
} else if (atlasConversionConcern.equals(AtlasConversionConcern.UNSUPPORTED)) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(message);
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.core.validate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.core.AtlasPath;
|
||||
import io.atlasmap.spi.FieldDirection;
|
||||
import io.atlasmap.v2.Field;
|
||||
import io.atlasmap.v2.Validation;
|
||||
import io.atlasmap.v2.ValidationScope;
|
||||
import io.atlasmap.v2.ValidationStatus;
|
||||
|
||||
public class MultipleFieldSelectionValidator {
|
||||
|
||||
private BaseModuleValidationService<?> service;
|
||||
|
||||
public MultipleFieldSelectionValidator(BaseModuleValidationService<?> service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void validate(List<Validation> validations, String mappingId, FieldDirection direction, List<Field> fields) {
|
||||
if (fields.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
for (Field f : fields) {
|
||||
if (!service.matchDocIdOrNull(f.getDocId())) {
|
||||
continue;
|
||||
}
|
||||
AtlasPath path = new AtlasPath(f.getPath());
|
||||
if (path.hasCollection()) {
|
||||
Validation validation = new Validation();
|
||||
validation.setScope(ValidationScope.MAPPING);
|
||||
validation.setId(mappingId);
|
||||
validation.setMessage(String.format(
|
||||
"A %s field contained in a collection can not be selected with other %s field: ['%s']",
|
||||
direction.value(), direction.value(), f.getPath()));
|
||||
validation.setStatus(ValidationStatus.ERROR);
|
||||
validations.add(validation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-libs
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package io.atlasmap.entaxy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
import ru.entaxy.platform.modules.datamapper.DataMapper;
|
||||
import ru.entaxy.platform.modules.datamapper.DataMapperService;
|
||||
|
||||
public class DataMapperLookup implements ValuesLookup {
|
||||
|
||||
public List<String> getValues() {
|
||||
List<String> result = null;
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(DataMapper.class).getBundleContext();
|
||||
if (bundleContext == null)
|
||||
return null;
|
||||
ServiceReference<DataMapperService> ref =
|
||||
bundleContext.getServiceReference(DataMapperService.class);
|
||||
if (ref == null)
|
||||
return null;
|
||||
DataMapperService dataMapperService = bundleContext.getService(ref);
|
||||
if (dataMapperService != null)
|
||||
result = dataMapperService.getMapSignaturesSorted();
|
||||
try {
|
||||
bundleContext.ungetService(ref);
|
||||
} catch (Exception ignore) {
|
||||
// noop
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-libs
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package io.atlasmap.entaxy;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
|
||||
public class OsgiHelper {
|
||||
|
||||
public static BundleContext bundleContext = FrameworkUtil.getBundle(CommonUtils.class).getBundleContext();
|
||||
|
||||
public static <T> ServiceReference<T> getServiceRef(Class<T> serviceClass) {
|
||||
return bundleContext.getServiceReference(serviceClass);
|
||||
}
|
||||
|
||||
public static <T> T getService(ServiceReference<T> serviceRef) {
|
||||
return bundleContext.getService(serviceRef);
|
||||
}
|
||||
|
||||
public static <T> void ungetService(ServiceReference<T> serviceRef) {
|
||||
bundleContext.ungetService(serviceRef);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-libs
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package io.atlasmap.entaxy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ValuesLookup {
|
||||
|
||||
default String getId() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
List<String> getValues();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-libs
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package io.atlasmap.entaxy;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ValuesLookupService {
|
||||
|
||||
protected static Map<String, ValuesLookup> lookups = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
static {
|
||||
addLookup(new DataMapperLookup());
|
||||
}
|
||||
|
||||
public static void addLookup(ValuesLookup lookup) {
|
||||
lookups.put(lookup.getId(), lookup);
|
||||
}
|
||||
|
||||
public static void removeLookup(ValuesLookup lookup) {
|
||||
lookups.remove(lookup.getId());
|
||||
}
|
||||
|
||||
|
||||
public static List<String> lookupValues(String id) {
|
||||
if (!lookups.containsKey(id))
|
||||
return null;
|
||||
return lookups.get(id).getValues();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import io.atlasmap.expression.internal.LRUCache;
|
||||
import io.atlasmap.expression.parser.ParseException;
|
||||
import io.atlasmap.expression.parser.Parser;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
/**
|
||||
*
|
||||
* Parses and evaluates a simple expression language. This was originally based
|
||||
* on the selector expression language found in ActiveMQ. It was modified so that
|
||||
* it's supports custom functions and it's comparison expressions were less SQL like,
|
||||
* and more script like.
|
||||
*
|
||||
*/
|
||||
public interface Expression {
|
||||
|
||||
LRUCache<String, Object> CACHE = new LRUCache<>(100);
|
||||
|
||||
/**
|
||||
* Execute the expression against the given context.
|
||||
*
|
||||
* @param expressionContext {@link ExpressionContext}
|
||||
* @return {@link Field} represents a result
|
||||
* @throws ExpressionException If evaluation fails
|
||||
*/
|
||||
Field evaluate(ExpressionContext expressionContext) throws ExpressionException;
|
||||
|
||||
static Expression parse(String expessionText, FunctionResolver functionResolver) throws ExpressionException {
|
||||
if (functionResolver == null) {
|
||||
functionResolver = (name, args) -> {
|
||||
throw new ParseException("Function not found: " + name);
|
||||
};
|
||||
}
|
||||
Object result = CACHE.get(expessionText);
|
||||
if (result instanceof ExpressionException) {
|
||||
throw (ExpressionException) result;
|
||||
} else if (result instanceof Expression) {
|
||||
return (Expression) result;
|
||||
} else {
|
||||
String actual = expessionText;
|
||||
try {
|
||||
Parser parser = new Parser(new StringReader(actual));
|
||||
parser.functionResolver = functionResolver;
|
||||
Expression e = parser.parse();
|
||||
CACHE.put(expessionText, e);
|
||||
return e;
|
||||
} catch (Throwable e) {
|
||||
ExpressionException fe = new ExpressionException(actual, e);
|
||||
CACHE.put(expessionText, fe);
|
||||
throw fe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clearCache() {
|
||||
CACHE.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression;
|
||||
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
/**
|
||||
* A Filterable is the object being evaluated by the filters. It provides
|
||||
* access to filtered properties.
|
||||
*
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public interface ExpressionContext {
|
||||
|
||||
/**
|
||||
* Extracts the named variable.
|
||||
*
|
||||
* @param name variable name
|
||||
* @return {@link Field} represents variable value
|
||||
* @throws ExpressionException If variable cannot be retrieved
|
||||
*/
|
||||
Field getVariable(String name) throws ExpressionException;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression;
|
||||
|
||||
public class ExpressionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -6892363158919485507L;
|
||||
|
||||
public ExpressionException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ExpressionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ExpressionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ExpressionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.expression.parser.ParseException;
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface FunctionResolver {
|
||||
Expression resolve(String functionName, List<Expression> args) throws ParseException;
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
import static io.atlasmap.v2.AtlasModelFactory.wrapWithField;
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
/**
|
||||
* An expression which performs an operation on two expression values.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public abstract class ArithmeticExpression extends BinaryExpression {
|
||||
|
||||
protected static final int INTEGER = 1;
|
||||
protected static final int LONG = 2;
|
||||
protected static final int DOUBLE = 3;
|
||||
boolean convertStringExpressions = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param left The left {@link Expression}
|
||||
* @param right The right {@link Expression}
|
||||
*/
|
||||
public ArithmeticExpression(Expression left, Expression right) {
|
||||
super(left, right);
|
||||
convertStringExpressions = ComparisonExpression.CONVERT_STRING_EXPRESSIONS.get()!=null;
|
||||
}
|
||||
|
||||
public static Expression createPlus(Expression left, Expression right) {
|
||||
return new ArithmeticExpression(left, right) {
|
||||
protected Field evaluate(Field lfield, Field rfield) {
|
||||
Object lvalue = lfield.getValue();
|
||||
Object rvalue = rfield.getValue();
|
||||
if (lvalue instanceof String) {
|
||||
String text = (String)lvalue;
|
||||
String answer = text + rvalue;
|
||||
return wrapWithField(answer);
|
||||
} else {
|
||||
return wrapWithField(plus(asNumber(lvalue), asNumber(rvalue)));
|
||||
}
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "+";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Expression createMinus(Expression left, Expression right) {
|
||||
return new ArithmeticExpression(left, right) {
|
||||
protected Field evaluate(Field lfield, Field rfield) {
|
||||
Object lvalue = lfield.getValue();
|
||||
Object rvalue = rfield.getValue();
|
||||
return wrapWithField(minus(asNumber(lvalue), asNumber(rvalue)));
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "-";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Expression createMultiply(Expression left, Expression right) {
|
||||
return new ArithmeticExpression(left, right) {
|
||||
|
||||
protected Field evaluate(Field lfield, Field rfield) {
|
||||
Object lvalue = lfield.getValue();
|
||||
Object rvalue = rfield.getValue();
|
||||
return wrapWithField(multiply(asNumber(lvalue), asNumber(rvalue)));
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "*";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Expression createDivide(Expression left, Expression right) {
|
||||
return new ArithmeticExpression(left, right) {
|
||||
|
||||
protected Field evaluate(Field lfield, Field rfield) {
|
||||
Object lvalue = lfield.getValue();
|
||||
Object rvalue = rfield.getValue();
|
||||
return wrapWithField(divide(asNumber(lvalue), asNumber(rvalue)));
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "/";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Expression createMod(Expression left, Expression right) {
|
||||
return new ArithmeticExpression(left, right) {
|
||||
|
||||
protected Field evaluate(Field lfield, Field rfield) {
|
||||
Object lvalue = lfield.getValue();
|
||||
Object rvalue = rfield.getValue();
|
||||
return wrapWithField(mod(asNumber(lvalue), asNumber(rvalue)));
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "%";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Number plus(Number left, Number right) {
|
||||
switch (numberType(left, right)) {
|
||||
case INTEGER:
|
||||
return new Integer(left.intValue() + right.intValue());
|
||||
case LONG:
|
||||
return new Long(left.longValue() + right.longValue());
|
||||
default:
|
||||
return new Double(left.doubleValue() + right.doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
protected Number minus(Number left, Number right) {
|
||||
switch (numberType(left, right)) {
|
||||
case INTEGER:
|
||||
return new Integer(left.intValue() - right.intValue());
|
||||
case LONG:
|
||||
return new Long(left.longValue() - right.longValue());
|
||||
default:
|
||||
return new Double(left.doubleValue() - right.doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
protected Number multiply(Number left, Number right) {
|
||||
switch (numberType(left, right)) {
|
||||
case INTEGER:
|
||||
return new Integer(left.intValue() * right.intValue());
|
||||
case LONG:
|
||||
return new Long(left.longValue() * right.longValue());
|
||||
default:
|
||||
return new Double(left.doubleValue() * right.doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
protected Number divide(Number left, Number right) {
|
||||
return new Double(left.doubleValue() / right.doubleValue());
|
||||
}
|
||||
|
||||
protected Number mod(Number left, Number right) {
|
||||
return new Double(left.doubleValue() % right.doubleValue());
|
||||
}
|
||||
|
||||
private int numberType(Number left, Number right) {
|
||||
if (isDouble(left) || isDouble(right)) {
|
||||
return DOUBLE;
|
||||
} else if (left instanceof Long || right instanceof Long) {
|
||||
return LONG;
|
||||
} else {
|
||||
return INTEGER;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDouble(Number n) {
|
||||
return n instanceof Float || n instanceof Double;
|
||||
}
|
||||
|
||||
protected Number asNumber(Object value) {
|
||||
if (value instanceof Number) {
|
||||
return (Number)value;
|
||||
} else {
|
||||
if( convertStringExpressions && value instanceof String) {
|
||||
String v = (String) value;
|
||||
try {
|
||||
if( v.contains(".") ) {
|
||||
return new Double(v);
|
||||
} else {
|
||||
return new Long(v);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new RuntimeException("Cannot convert value: " + value + " into a number");
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Cannot convert value: " + value + " into a number");
|
||||
}
|
||||
}
|
||||
|
||||
public Field evaluate(ExpressionContext message) throws ExpressionException {
|
||||
Field lfield = left.evaluate(message);
|
||||
if (lfield == null || lfield.getValue() == null) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
Field rfield = right.evaluate(message);
|
||||
if (rfield == null || rfield.getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
return evaluate(lfield, rfield);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate expression.
|
||||
* @param lvalue {@link Field} represents left value
|
||||
* @param rvalue {@link Field} represents right value
|
||||
* @return {@link Field} reporesents a result
|
||||
*/
|
||||
protected abstract Field evaluate(Field lvalue, Field rvalue);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
|
||||
/**
|
||||
* An expression which performs an operation on two expression values.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public abstract class BinaryExpression implements Expression {
|
||||
protected Expression left;
|
||||
protected Expression right;
|
||||
|
||||
public BinaryExpression(Expression left, Expression right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public Expression getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public Expression getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String toString() {
|
||||
return "(" + left.toString() + " " + getExpressionSymbol() + " " + right.toString() + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* TODO: more efficient hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == null || !this.getClass().equals(o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
return toString().equals(o.toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the symbol that represents this binary expression. For example, addition is
|
||||
* represented by "+"
|
||||
*
|
||||
* @return expression symbol string
|
||||
*/
|
||||
public abstract String getExpressionSymbol();
|
||||
|
||||
/**
|
||||
* @param expression right {@link Expression}
|
||||
*/
|
||||
public void setRight(Expression expression) {
|
||||
right = expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expression left {@link Expression}
|
||||
*/
|
||||
public void setLeft(Expression expression) {
|
||||
left = expression;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.expression.parser.ParseException;
|
||||
|
||||
/**
|
||||
* A BooleanExpression is an expression that always
|
||||
* produces a Boolean result.
|
||||
*
|
||||
*/
|
||||
public interface BooleanExpression extends Expression {
|
||||
|
||||
/**
|
||||
* @param message expression context
|
||||
* @return true if the expression evaluates to Boolean.TRUE.
|
||||
* @throws ExpressionException exception
|
||||
*/
|
||||
boolean matches(ExpressionContext message) throws ExpressionException;
|
||||
|
||||
static BooleanExpression asBooleanExpression(Expression value) throws ParseException {
|
||||
if (value instanceof BooleanExpression) {
|
||||
return (BooleanExpression) value;
|
||||
}
|
||||
if (value instanceof VariableExpression) {
|
||||
return UnaryExpression.createBooleanCast( value );
|
||||
}
|
||||
throw new ParseException("Expression will not result in a boolean value: " + value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
import static io.atlasmap.v2.AtlasModelFactory.wrapWithField;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
|
||||
/**
|
||||
* A filter performing a comparison of two objects.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression {
|
||||
|
||||
public static final ThreadLocal<Boolean> CONVERT_STRING_EXPRESSIONS = new ThreadLocal<Boolean>();
|
||||
private static final Set<Character> REGEXP_CONTROL_CHARS = new HashSet<Character>();
|
||||
|
||||
boolean convertStringExpressions = false;
|
||||
|
||||
/**
|
||||
* @param left left {@link Expression}
|
||||
* @param right right {@link Expression}
|
||||
*/
|
||||
public ComparisonExpression(Expression left, Expression right) {
|
||||
super(left, right);
|
||||
convertStringExpressions = CONVERT_STRING_EXPRESSIONS.get()!=null;
|
||||
}
|
||||
|
||||
public static BooleanExpression createBetween(Expression value, Expression left, Expression right) {
|
||||
return LogicExpression.createAND(createGreaterThanEqual(value, left), createLessThanEqual(value, right));
|
||||
}
|
||||
|
||||
public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right) {
|
||||
return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right));
|
||||
}
|
||||
|
||||
static {
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('.'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('\\'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('['));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf(']'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('^'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('$'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('?'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('*'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('+'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('{'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('}'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('|'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('('));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf(')'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf(':'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('&'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('<'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('>'));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('='));
|
||||
REGEXP_CONTROL_CHARS.add(Character.valueOf('!'));
|
||||
}
|
||||
|
||||
static class LikeExpression extends UnaryExpression implements BooleanExpression {
|
||||
|
||||
Pattern likePattern;
|
||||
|
||||
LikeExpression(Expression right, String like, int escape) {
|
||||
super(right);
|
||||
|
||||
StringBuffer regexp = new StringBuffer(like.length() * 2);
|
||||
regexp.append("\\A"); // The beginning of the input
|
||||
for (int i = 0; i < like.length(); i++) {
|
||||
char c = like.charAt(i);
|
||||
if (escape == (0xFFFF & c)) {
|
||||
i++;
|
||||
if (i >= like.length()) {
|
||||
// nothing left to escape...
|
||||
break;
|
||||
}
|
||||
|
||||
char t = like.charAt(i);
|
||||
regexp.append("\\x");
|
||||
regexp.append(Integer.toHexString(0xFFFF & t));
|
||||
} else if (c == '%') {
|
||||
regexp.append(".*?"); // Do a non-greedy match
|
||||
} else if (c == '_') {
|
||||
regexp.append("."); // match one
|
||||
} else if (REGEXP_CONTROL_CHARS.contains(new Character(c))) {
|
||||
regexp.append("\\x");
|
||||
regexp.append(Integer.toHexString(0xFFFF & c));
|
||||
} else {
|
||||
regexp.append(c);
|
||||
}
|
||||
}
|
||||
regexp.append("\\z"); // The end of the input
|
||||
|
||||
likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activemq.filter.UnaryExpression#getExpressionSymbol()
|
||||
*/
|
||||
public String getExpressionSymbol() {
|
||||
return "LIKE";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activemq.filter.Expression#evaluate(ExpressionContext)
|
||||
*/
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
|
||||
Object rv = this.getRight().evaluate(expressionContext).getValue();
|
||||
|
||||
if (rv == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(rv instanceof String)) {
|
||||
return wrapWithField(Boolean.FALSE);
|
||||
// throw new RuntimeException("LIKE can only operate on String
|
||||
// identifiers. LIKE attemped on: '" + rv.getClass());
|
||||
}
|
||||
|
||||
return wrapWithField(likePattern.matcher((String)rv).matches() ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
public boolean matches(ExpressionContext message) throws ExpressionException {
|
||||
Object object = evaluate(message).getValue();
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
public static BooleanExpression createLike(Expression left, String right, String escape) {
|
||||
if (escape != null && escape.length() != 1) {
|
||||
throw new RuntimeException("The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape);
|
||||
}
|
||||
int c = -1;
|
||||
if (escape != null) {
|
||||
c = 0xFFFF & escape.charAt(0);
|
||||
}
|
||||
|
||||
return new LikeExpression(left, right, c);
|
||||
}
|
||||
|
||||
public static BooleanExpression createNotLike(Expression left, String right, String escape) {
|
||||
return UnaryExpression.createNOT(createLike(left, right, escape));
|
||||
}
|
||||
|
||||
public static BooleanExpression createInFilter(Expression left, List elements) {
|
||||
|
||||
if (!(left instanceof VariableExpression)) {
|
||||
throw new RuntimeException("Expected a property for In expression, got: " + left);
|
||||
}
|
||||
return UnaryExpression.createInExpression((VariableExpression)left, elements, false);
|
||||
|
||||
}
|
||||
|
||||
public static BooleanExpression createNotInFilter(Expression left, List elements) {
|
||||
|
||||
if (!(left instanceof VariableExpression)) {
|
||||
throw new RuntimeException("Expected a property for In expression, got: " + left);
|
||||
}
|
||||
return UnaryExpression.createInExpression((VariableExpression)left, elements, true);
|
||||
|
||||
}
|
||||
|
||||
public static BooleanExpression createIsNull(Expression left) {
|
||||
return doCreateEqual(left, ConstantExpression.NULL);
|
||||
}
|
||||
|
||||
public static BooleanExpression createIsNotNull(Expression left) {
|
||||
return UnaryExpression.createNOT(doCreateEqual(left, ConstantExpression.NULL));
|
||||
}
|
||||
|
||||
public static BooleanExpression createNotEqual(Expression left, Expression right) {
|
||||
return UnaryExpression.createNOT(createEqual(left, right));
|
||||
}
|
||||
|
||||
public static BooleanExpression createEqual(Expression left, Expression right) {
|
||||
checkEqualOperandCompatability(left, right);
|
||||
return doCreateEqual(left, right);
|
||||
}
|
||||
|
||||
private static BooleanExpression doCreateEqual(Expression left, Expression right) {
|
||||
return new ComparisonExpression(left, right) {
|
||||
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
Object lv = left.evaluate(expressionContext).getValue();
|
||||
Object rv = right.evaluate(expressionContext).getValue();
|
||||
|
||||
// If one of the values is null
|
||||
if (lv == null ^ rv == null) {
|
||||
return wrapWithField(Boolean.FALSE);
|
||||
}
|
||||
if (lv == rv || lv.equals(rv)) {
|
||||
return wrapWithField(Boolean.TRUE);
|
||||
}
|
||||
if (lv instanceof Comparable && rv instanceof Comparable) {
|
||||
return wrapWithField(compare((Comparable)lv, (Comparable)rv));
|
||||
}
|
||||
return wrapWithField(Boolean.FALSE);
|
||||
}
|
||||
|
||||
protected boolean asBoolean(int answer) {
|
||||
return answer == 0;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "==";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createGreaterThan(final Expression left, final Expression right) {
|
||||
checkLessThanOperand(left);
|
||||
checkLessThanOperand(right);
|
||||
return new ComparisonExpression(left, right) {
|
||||
protected boolean asBoolean(int answer) {
|
||||
return answer > 0;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return ">";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) {
|
||||
checkLessThanOperand(left);
|
||||
checkLessThanOperand(right);
|
||||
return new ComparisonExpression(left, right) {
|
||||
protected boolean asBoolean(int answer) {
|
||||
return answer >= 0;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return ">=";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createLessThan(final Expression left, final Expression right) {
|
||||
checkLessThanOperand(left);
|
||||
checkLessThanOperand(right);
|
||||
return new ComparisonExpression(left, right) {
|
||||
|
||||
protected boolean asBoolean(int answer) {
|
||||
return answer < 0;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "<";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) {
|
||||
checkLessThanOperand(left);
|
||||
checkLessThanOperand(right);
|
||||
return new ComparisonExpression(left, right) {
|
||||
|
||||
protected boolean asBoolean(int answer) {
|
||||
return answer <= 0;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "<=";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Only Numeric expressions can be used in >, >=, < or <= expressions.
|
||||
*
|
||||
* @param expr {@link Expression}
|
||||
*/
|
||||
public static void checkLessThanOperand(Expression expr) {
|
||||
if (expr instanceof ConstantExpression) {
|
||||
Object value = ((ConstantExpression)expr).getValue();
|
||||
if (value instanceof Number) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Else it's boolean or a String..
|
||||
throw new RuntimeException("Value '" + expr + "' cannot be compared.");
|
||||
}
|
||||
if (expr instanceof BooleanExpression) {
|
||||
throw new RuntimeException("Value '" + expr + "' cannot be compared.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param left left {@link Expression}
|
||||
* @param right right {@link Expression}
|
||||
*/
|
||||
private static void checkEqualOperandCompatability(Expression left, Expression right) {
|
||||
if (left instanceof ConstantExpression && right instanceof ConstantExpression) {
|
||||
if (left instanceof BooleanExpression && !(right instanceof BooleanExpression)) {
|
||||
throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
Comparable<Comparable> lv = (Comparable)left.evaluate(expressionContext).getValue();
|
||||
if (lv == null) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
Comparable rv = (Comparable)right.evaluate(expressionContext).getValue();
|
||||
if (rv == null) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
return wrapWithField(compare(lv, rv));
|
||||
}
|
||||
|
||||
protected Boolean compare(Comparable lv, Comparable rv) {
|
||||
Class<? extends Comparable> lc = lv.getClass();
|
||||
Class<? extends Comparable> rc = rv.getClass();
|
||||
// If the the objects are not of the same type,
|
||||
// try to convert up to allow the comparison.
|
||||
if (lc != rc) {
|
||||
try {
|
||||
if (lc == Boolean.class) {
|
||||
if (convertStringExpressions && rc == String.class) {
|
||||
rv = Boolean.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == Byte.class) {
|
||||
if (rc == Short.class) {
|
||||
lv = Short.valueOf(((Number)lv).shortValue());
|
||||
} else if (rc == Integer.class) {
|
||||
lv = Integer.valueOf(((Number)lv).intValue());
|
||||
} else if (rc == Long.class) {
|
||||
lv = Long.valueOf(((Number)lv).longValue());
|
||||
} else if (rc == Float.class) {
|
||||
lv = new Float(((Number)lv).floatValue());
|
||||
} else if (rc == Double.class) {
|
||||
lv = new Double(((Number)lv).doubleValue());
|
||||
} else if (rc == BigInteger.class) {
|
||||
lv = BigInteger.valueOf((Byte)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = BigDecimal.valueOf((Byte)lv);
|
||||
} else if (convertStringExpressions && rc == String.class) {
|
||||
rv = Byte.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == Short.class) {
|
||||
if (rc == Integer.class) {
|
||||
lv = Integer.valueOf(((Number)lv).intValue());
|
||||
} else if (rc == Long.class) {
|
||||
lv = Long.valueOf(((Number)lv).longValue());
|
||||
} else if (rc == Float.class) {
|
||||
lv = new Float(((Number)lv).floatValue());
|
||||
} else if (rc == Double.class) {
|
||||
lv = new Double(((Number)lv).doubleValue());
|
||||
} else if (rc == BigInteger.class) {
|
||||
lv = BigInteger.valueOf((Short)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = BigDecimal.valueOf((Short)lv);
|
||||
} else if (convertStringExpressions && rc == String.class) {
|
||||
rv = Short.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == Integer.class) {
|
||||
if (rc == Long.class) {
|
||||
lv = Long.valueOf(((Number)lv).longValue());
|
||||
} else if (rc == Float.class) {
|
||||
lv = new Float(((Number)lv).floatValue());
|
||||
} else if (rc == Double.class) {
|
||||
lv = new Double(((Number)lv).doubleValue());
|
||||
} else if (rc == BigInteger.class) {
|
||||
lv = BigInteger.valueOf((Integer)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = BigDecimal.valueOf((Integer)lv);
|
||||
} else if (convertStringExpressions && rc == String.class) {
|
||||
rv = Integer.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == Long.class) {
|
||||
if (rc == Integer.class) {
|
||||
rv = Long.valueOf(((Number)rv).longValue());
|
||||
} else if (rc == Float.class) {
|
||||
lv = new Float(((Number)lv).floatValue());
|
||||
} else if (rc == Double.class) {
|
||||
lv = new Double(((Number)lv).doubleValue());
|
||||
} else if (rc == BigInteger.class) {
|
||||
lv = BigInteger.valueOf((Long)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = BigDecimal.valueOf((Long)lv);
|
||||
} else if (convertStringExpressions && rc == String.class) {
|
||||
rv = Long.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == Float.class) {
|
||||
if (rc == Integer.class) {
|
||||
rv = new Float(((Number)rv).floatValue());
|
||||
} else if (rc == Long.class) {
|
||||
rv = new Float(((Number)rv).floatValue());
|
||||
} else if (rc == Double.class) {
|
||||
lv = new Double(((Number)lv).doubleValue());
|
||||
} else if (rc == BigInteger.class) {
|
||||
rv = new BigDecimal((BigInteger)rv);
|
||||
lv = BigDecimal.valueOf((Float)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = BigDecimal.valueOf((Float)lv);
|
||||
} else if (convertStringExpressions && rc == String.class) {
|
||||
rv = Float.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == Double.class) {
|
||||
if (rc == Integer.class) {
|
||||
rv = new Double(((Number)rv).doubleValue());
|
||||
} else if (rc == Long.class) {
|
||||
rv = new Double(((Number)rv).doubleValue());
|
||||
} else if (rc == Float.class) {
|
||||
rv = new Double(((Number)rv).doubleValue());
|
||||
} else if (rc == BigInteger.class) {
|
||||
rv = new BigDecimal((BigInteger)rv);
|
||||
lv = BigDecimal.valueOf((Double)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = BigDecimal.valueOf((Double)lv);
|
||||
} else if (convertStringExpressions && rc == String.class) {
|
||||
rv = Double.valueOf((String)rv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (convertStringExpressions && lc == String.class) {
|
||||
|
||||
if (rc == Boolean.class) {
|
||||
lv = Boolean.valueOf((String)lv);
|
||||
} else if (rc == Byte.class) {
|
||||
lv = Byte.valueOf((String)lv);
|
||||
} else if (rc == Short.class) {
|
||||
lv = Short.valueOf((String)lv);
|
||||
} else if (rc == Integer.class) {
|
||||
lv = Integer.valueOf((String)lv);
|
||||
} else if (rc == Long.class) {
|
||||
lv = Long.valueOf((String)lv);
|
||||
} else if (rc == Float.class) {
|
||||
lv = Float.valueOf((String)lv);
|
||||
} else if (rc == Double.class) {
|
||||
lv = Double.valueOf((String)lv);
|
||||
} else if (rc == BigInteger.class) {
|
||||
lv = new BigInteger((String)lv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = new BigDecimal((String)lv);
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == BigInteger.class) {
|
||||
if (rc == Byte.class) {
|
||||
rv = BigInteger.valueOf(((Byte)rv));
|
||||
} else if (rc == Short.class) {
|
||||
rv = BigInteger.valueOf((Short)rv);
|
||||
} else if (rc == Integer.class) {
|
||||
rv = BigInteger.valueOf((Integer)rv);
|
||||
} else if (rc == Long.class) {
|
||||
rv = BigInteger.valueOf((Long)rv);
|
||||
} else if (rc == Float.class) {
|
||||
lv = new BigDecimal((BigInteger)lv);
|
||||
rv = BigDecimal.valueOf(((Float)rv));
|
||||
} else if (rc == Double.class) {
|
||||
lv = new BigDecimal((BigInteger)lv);
|
||||
rv = BigDecimal.valueOf((Double)rv);
|
||||
} else if (rc == BigDecimal.class) {
|
||||
lv = new BigDecimal((BigInteger)lv);
|
||||
} else if (rc != BigInteger.class) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else if (lc == BigDecimal.class) {
|
||||
if (rc == Byte.class) {
|
||||
rv = BigDecimal.valueOf((Byte)rv);
|
||||
} else if (rc == Short.class) {
|
||||
rv = BigDecimal.valueOf((Short)rv);
|
||||
} else if (rc == Integer.class) {
|
||||
rv = BigDecimal.valueOf((Integer)rv);
|
||||
} else if (rc == Long.class) {
|
||||
rv = BigDecimal.valueOf((Long)rv);
|
||||
} else if (rc == Float.class) {
|
||||
rv = BigDecimal.valueOf((Float)rv);
|
||||
} else if (rc == Double.class) {
|
||||
rv = BigDecimal.valueOf((Double)rv);
|
||||
} else if (rc == BigInteger.class) {
|
||||
rv = new BigDecimal((BigInteger)rv);
|
||||
} else if (rc != BigDecimal.class) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
protected abstract boolean asBoolean(int answer);
|
||||
|
||||
public boolean matches(ExpressionContext message) throws ExpressionException {
|
||||
Object object = evaluate(message).getValue();
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
import static io.atlasmap.v2.AtlasModelFactory.wrapWithField;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a constant expression.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class ConstantExpression implements Expression {
|
||||
|
||||
static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression {
|
||||
BooleanConstantExpression(Object value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
public boolean matches(ExpressionContext message) throws ExpressionException {
|
||||
Object object = evaluate(message);
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null);
|
||||
public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE);
|
||||
public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE);
|
||||
|
||||
private Object value;
|
||||
|
||||
public ConstantExpression(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ConstantExpression createFromDecimal(String text) {
|
||||
|
||||
// Strip off the 'l' or 'L' if needed.
|
||||
if (text.endsWith("l") || text.endsWith("L")) {
|
||||
text = text.substring(0, text.length() - 1);
|
||||
}
|
||||
|
||||
Number value;
|
||||
try {
|
||||
value = new Long(text);
|
||||
} catch (NumberFormatException e) {
|
||||
// The number may be too big to fit in a long.
|
||||
value = new BigDecimal(text);
|
||||
}
|
||||
|
||||
long l = value.longValue();
|
||||
if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
|
||||
value = Integer.valueOf(value.intValue());
|
||||
}
|
||||
return new ConstantExpression(value);
|
||||
}
|
||||
|
||||
public static ConstantExpression createFromHex(String text) {
|
||||
Number value = Long.valueOf(Long.parseLong(text.substring(2), 16));
|
||||
long l = value.longValue();
|
||||
if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
|
||||
value = Integer.valueOf(value.intValue());
|
||||
}
|
||||
return new ConstantExpression(value);
|
||||
}
|
||||
|
||||
public static ConstantExpression createFromOctal(String text) {
|
||||
Number value = Long.valueOf(Long.parseLong(text, 8));
|
||||
long l = value.longValue();
|
||||
if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
|
||||
value = Integer.valueOf(value.intValue());
|
||||
}
|
||||
return new ConstantExpression(value);
|
||||
}
|
||||
|
||||
public static ConstantExpression createFloat(String text) {
|
||||
Number value = new Double(text);
|
||||
return new ConstantExpression(value);
|
||||
}
|
||||
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
return wrapWithField(value);
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String toString() {
|
||||
if (value == null) {
|
||||
return "NULL";
|
||||
}
|
||||
if (value instanceof Boolean) {
|
||||
return ((Boolean)value).booleanValue() ? "TRUE" : "FALSE";
|
||||
}
|
||||
if (value instanceof String) {
|
||||
return encodeString((String)value);
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* TODO: more efficient hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* TODO: more efficient hashCode()
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == null || !this.getClass().equals(o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
return toString().equals(o.toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the value of string so that it looks like it would look like when
|
||||
* it was provided in a selector.
|
||||
*
|
||||
* @param s {@link String} to encode
|
||||
* @return encoded {@link String}
|
||||
*/
|
||||
public static String encodeString(String s) {
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append('\'');
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '\'') {
|
||||
b.append(c);
|
||||
}
|
||||
b.append(c);
|
||||
}
|
||||
b.append('\'');
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A Simple LRU Cache.
|
||||
*
|
||||
* @param <K> key
|
||||
* @param <V> value
|
||||
*/
|
||||
|
||||
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
|
||||
private static final long serialVersionUID = -342098639681884413L;
|
||||
protected int maxCacheSize = 10000;
|
||||
|
||||
/**
|
||||
* Default constructor for an LRU Cache The default capacity is 10000.
|
||||
*/
|
||||
public LRUCache() {
|
||||
this(0,10000, 0.75f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a LRUCache with a maximum capacity.
|
||||
*
|
||||
* @param maximumCacheSize maximum cache size
|
||||
*/
|
||||
public LRUCache(int maximumCacheSize) {
|
||||
this(0, maximumCacheSize, 0.75f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty {@code LRUCache} instance with the specified
|
||||
* initial capacity, maximumCacheSize,load factor and ordering mode.
|
||||
*
|
||||
* @param initialCapacity the initial capacity.
|
||||
* @param maximumCacheSize maximum cache size
|
||||
* @param loadFactor the load factor.
|
||||
* @param accessOrder the ordering mode - {@code true} for access-order,
|
||||
* {@code false} for insertion-order.
|
||||
* @throws IllegalArgumentException if the initial capacity is negative or
|
||||
* the load factor is non-positive.
|
||||
*/
|
||||
|
||||
public LRUCache(int initialCapacity, int maximumCacheSize, float loadFactor, boolean accessOrder) {
|
||||
super(initialCapacity, loadFactor, accessOrder);
|
||||
this.maxCacheSize = maximumCacheSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the maxCacheSize.
|
||||
*/
|
||||
public int getMaxCacheSize() {
|
||||
return maxCacheSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param maxCacheSize The maxCacheSize to set.
|
||||
*/
|
||||
public void setMaxCacheSize(int maxCacheSize) {
|
||||
this.maxCacheSize = maxCacheSize;
|
||||
}
|
||||
|
||||
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
|
||||
if( size() > maxCacheSize ) {
|
||||
onCacheEviction(eldest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void onCacheEviction(Map.Entry<K,V> eldest) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
import static io.atlasmap.v2.AtlasModelFactory.wrapWithField;
|
||||
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
/**
|
||||
* A filter performing a comparison of two objects.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public abstract class LogicExpression extends BinaryExpression implements BooleanExpression {
|
||||
|
||||
/**
|
||||
* @param left left {@link BooleanExpression}
|
||||
* @param right right {@link BooleanExpression}
|
||||
*/
|
||||
public LogicExpression(BooleanExpression left, BooleanExpression right) {
|
||||
super(left, right);
|
||||
}
|
||||
|
||||
public static BooleanExpression createOR(BooleanExpression lvalue, BooleanExpression rvalue) {
|
||||
return new LogicExpression(lvalue, rvalue) {
|
||||
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
|
||||
Boolean lv = (Boolean)left.evaluate(expressionContext).getValue();
|
||||
// Can we do an OR shortcut??
|
||||
if (lv != null && lv.booleanValue()) {
|
||||
return wrapWithField(Boolean.TRUE);
|
||||
}
|
||||
|
||||
Boolean rv = (Boolean)right.evaluate(expressionContext).getValue();
|
||||
return wrapWithField(rv == null ? null : rv);
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "||";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createAND(BooleanExpression lvalue, BooleanExpression rvalue) {
|
||||
return new LogicExpression(lvalue, rvalue) {
|
||||
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
|
||||
Boolean lv = (Boolean)left.evaluate(expressionContext).getValue();
|
||||
|
||||
// Can we do an AND shortcut??
|
||||
if (lv == null) {
|
||||
return null;
|
||||
}
|
||||
if (!lv.booleanValue()) {
|
||||
return wrapWithField(Boolean.FALSE);
|
||||
}
|
||||
|
||||
Boolean rv = (Boolean)right.evaluate(expressionContext).getValue();
|
||||
return wrapWithField(rv == null ? null : rv);
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "&&";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public abstract Field evaluate(ExpressionContext expressionContext) throws ExpressionException;
|
||||
|
||||
public boolean matches(ExpressionContext message) throws ExpressionException {
|
||||
Object object = evaluate(message).getValue();
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
public final class Strings {
|
||||
|
||||
private Strings(){}
|
||||
|
||||
public static String stripPrefix(String string, String prefix) {
|
||||
if( string == null ) {
|
||||
return null;
|
||||
}
|
||||
if( prefix==null ) {
|
||||
return string;
|
||||
}
|
||||
if( string.startsWith(prefix) ) {
|
||||
return string.substring(prefix.length());
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
public static String stripSuffix(String string, String suffix) {
|
||||
if( string == null ) {
|
||||
return null;
|
||||
}
|
||||
if( suffix==null ) {
|
||||
return string;
|
||||
}
|
||||
if( string.endsWith(suffix) ) {
|
||||
return string.substring(0, string.length()-suffix.length());
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
import static io.atlasmap.v2.AtlasModelFactory.wrapWithField;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
|
||||
/**
|
||||
* An expression which performs an operation on two expression values.
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public abstract class UnaryExpression implements Expression {
|
||||
|
||||
private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE);
|
||||
protected Expression right;
|
||||
|
||||
public UnaryExpression(Expression left) {
|
||||
this.right = left;
|
||||
}
|
||||
|
||||
public static Expression createNegate(Expression left) {
|
||||
return new UnaryExpression(left) {
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
Object rvalue = right.evaluate(expressionContext).getValue();
|
||||
if (rvalue == null) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
if (rvalue instanceof Number) {
|
||||
return wrapWithField(negate((Number)rvalue));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "-";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createInExpression(VariableExpression right, List<Object> elements, final boolean not) {
|
||||
|
||||
// Use a HashSet if there are many elements.
|
||||
Collection<Object> t;
|
||||
if (elements.size() == 0) {
|
||||
t = null;
|
||||
} else if (elements.size() < 5) {
|
||||
t = elements;
|
||||
} else {
|
||||
t = new HashSet<Object>(elements);
|
||||
}
|
||||
final Collection<Object> inList = t;
|
||||
|
||||
return new BooleanUnaryExpression(right) {
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
|
||||
Object rvalue = right.evaluate(expressionContext).getValue();
|
||||
if (rvalue == null) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
if (rvalue.getClass() != String.class) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
|
||||
if ((inList != null && inList.contains(rvalue)) ^ not) {
|
||||
return wrapWithField(Boolean.TRUE);
|
||||
} else {
|
||||
return wrapWithField(Boolean.FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer answer = new StringBuffer();
|
||||
answer.append(right);
|
||||
answer.append(" ");
|
||||
answer.append(getExpressionSymbol());
|
||||
answer.append(" ( ");
|
||||
|
||||
int count = 0;
|
||||
for (Iterator<Object> i = inList.iterator(); i.hasNext();) {
|
||||
Object o = (Object)i.next();
|
||||
if (count != 0) {
|
||||
answer.append(", ");
|
||||
}
|
||||
answer.append(o);
|
||||
count++;
|
||||
}
|
||||
|
||||
answer.append(" )");
|
||||
return answer.toString();
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
if (not) {
|
||||
return "NOT IN";
|
||||
} else {
|
||||
return "IN";
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression {
|
||||
BooleanUnaryExpression(Expression left) {
|
||||
super(left);
|
||||
}
|
||||
|
||||
public boolean matches(ExpressionContext message) throws ExpressionException {
|
||||
Object object = evaluate(message).getValue();
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
public static BooleanExpression createNOT(BooleanExpression left) {
|
||||
return new BooleanUnaryExpression(left) {
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
Boolean lvalue = (Boolean)right.evaluate(expressionContext).getValue();
|
||||
if (lvalue == null) {
|
||||
return wrapWithField(null);
|
||||
}
|
||||
return wrapWithField(lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE);
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "!";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static BooleanExpression createBooleanCast(Expression left) {
|
||||
return new BooleanUnaryExpression(left) {
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
Object rvalue = right.evaluate(expressionContext).getValue();
|
||||
if (rvalue == null) {
|
||||
return null;
|
||||
}
|
||||
if (!rvalue.getClass().equals(Boolean.class)) {
|
||||
return wrapWithField(Boolean.FALSE);
|
||||
}
|
||||
return wrapWithField(((Boolean)rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return right.toString();
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Number negate(Number left) {
|
||||
Class clazz = left.getClass();
|
||||
if (clazz == Integer.class) {
|
||||
return new Integer(-left.intValue());
|
||||
} else if (clazz == Long.class) {
|
||||
return new Long(-left.longValue());
|
||||
} else if (clazz == Float.class) {
|
||||
return new Float(-left.floatValue());
|
||||
} else if (clazz == Double.class) {
|
||||
return new Double(-left.doubleValue());
|
||||
} else if (clazz == BigDecimal.class) {
|
||||
// We ussually get a big deciamal when we have Long.MIN_VALUE
|
||||
// constant in the
|
||||
// Selector. Long.MIN_VALUE is too big to store in a Long as a
|
||||
// positive so we store it
|
||||
// as a Big decimal. But it gets Negated right away.. to here we try
|
||||
// to covert it back
|
||||
// to a Long.
|
||||
BigDecimal bd = (BigDecimal)left;
|
||||
bd = bd.negate();
|
||||
|
||||
if (BD_LONG_MIN_VALUE.compareTo(bd) == 0) {
|
||||
return Long.valueOf(Long.MIN_VALUE);
|
||||
}
|
||||
return bd;
|
||||
} else {
|
||||
throw new RuntimeException("Don't know how to negate: " + left);
|
||||
}
|
||||
}
|
||||
|
||||
public Expression getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public void setRight(Expression expression) {
|
||||
right = expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String toString() {
|
||||
return "(" + getExpressionSymbol() + " " + right.toString() + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* TODO: more efficient hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* TODO: more efficient hashCode()
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == null || !this.getClass().equals(o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
return toString().equals(o.toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the symbol that represents this binary expression. For example,
|
||||
* addition is represented by "+"
|
||||
*
|
||||
* @return expression symbol string
|
||||
*/
|
||||
public abstract String getExpressionSymbol();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* atlasmap-entaxy-services
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*
|
||||
* 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 io.atlasmap.expression.internal;
|
||||
|
||||
|
||||
import io.atlasmap.expression.Expression;
|
||||
import io.atlasmap.expression.ExpressionContext;
|
||||
import io.atlasmap.expression.ExpressionException;
|
||||
import io.atlasmap.v2.Field;
|
||||
|
||||
/**
|
||||
* Represents a property expression.
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
*/
|
||||
public class VariableExpression implements Expression {
|
||||
|
||||
private final String name;
|
||||
|
||||
public VariableExpression(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Field evaluate(ExpressionContext expressionContext) throws ExpressionException {
|
||||
return expressionContext.getVariable(name);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String toString() {
|
||||
return "${" + name + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !this.getClass().equals(o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
return name.equals(((VariableExpression) o).name);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<!--
|
||||
~~~~~~licensing~~~~~~
|
||||
atlasmap-entaxy-services
|
||||
==========
|
||||
Copyright (C) 2020 - 2025 EmDev LLC
|
||||
==========
|
||||
You may not use this file except in accordance with the License Terms of the Copyright
|
||||
Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
Software for commercial purposes to provide services to third parties.
|
||||
|
||||
The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
Software provided by him will be suitable or not suitable for the specific purposes
|
||||
of the User, that the Software will meet all commercial and personal subjective
|
||||
expectations of the User, that the Software will work properly, without technical
|
||||
errors, quickly and uninterruptedly.
|
||||
|
||||
Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
or damage to data, property, etc.
|
||||
~~~~~~/licensing~~~~~~
|
||||
-->
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
Internal implementation details for the AtlasMap expression evaluator.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user