release version 1.10.0

This commit is contained in:
2024-12-14 04:07:49 +03:00
parent a5088587f7
commit c6b3d793c4
1916 changed files with 254306 additions and 0 deletions

View File

@ -0,0 +1,57 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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[]{};
}
}

View File

@ -0,0 +1,115 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,74 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,477 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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");
}
}

View File

@ -0,0 +1,129 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,335 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,188 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,52 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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() {
}
}

View File

@ -0,0 +1,70 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}

View File

@ -0,0 +1,97 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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> {
}

View File

@ -0,0 +1,61 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,49 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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 {
}

View File

@ -0,0 +1,63 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}

View File

@ -0,0 +1,108 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,52 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}

View File

@ -0,0 +1,169 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,134 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}

View File

@ -0,0 +1,287 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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));
}
}
}

View File

@ -0,0 +1,287 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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));
}
}
}

View File

@ -0,0 +1,151 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,177 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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());
}
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,176 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,387 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,184 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,209 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,118 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,262 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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());
}
}

View File

@ -0,0 +1,264 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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());
}
}

View File

@ -0,0 +1,104 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,197 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,208 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,217 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,209 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,213 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,239 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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()));
}
}
}

View File

@ -0,0 +1,199 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,93 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,96 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,104 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,176 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,176 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,176 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,220 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,516 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,559 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}
}

View File

@ -0,0 +1,565 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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=&quot;
*
*
* scheme: atlas module: stringseparated remaining: csv config: quoteChar=&quot;
*
* 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);
}
}
}
}

View File

@ -0,0 +1,432 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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");
}
}

View File

@ -0,0 +1,51 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,47 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}

View File

@ -0,0 +1,263 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,199 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,175 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,115 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}

View File

@ -0,0 +1,546 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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()));
}
}

View File

@ -0,0 +1,622 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,87 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,135 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}
}

View File

@ -0,0 +1,135 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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));
}
};
}
}
}

View File

@ -0,0 +1,144 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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 + "]";
}
}

View File

@ -0,0 +1,129 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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");
}
}
}

View File

@ -0,0 +1,443 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,339 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,99 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,517 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}
}

View File

@ -0,0 +1,382 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}

View File

@ -0,0 +1,155 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,93 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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());
}
}

View File

@ -0,0 +1,46 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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";
}

View File

@ -0,0 +1,432 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}
}
}

View File

@ -0,0 +1,213 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}
}

View File

@ -0,0 +1,82 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}
}
}

View File

@ -0,0 +1,102 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,63 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}

View File

@ -0,0 +1,63 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,51 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}

View File

@ -0,0 +1,246 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}

View File

@ -0,0 +1,118 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,73 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,560 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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 &gt;, &gt;=, &lt; or &lt;= 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;
}
}

View File

@ -0,0 +1,192 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}
}

View File

@ -0,0 +1,115 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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) {
}
}

View File

@ -0,0 +1,117 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,73 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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;
}
}

View File

@ -0,0 +1,277 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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();
}

View File

@ -0,0 +1,95 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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);
}
}

View File

@ -0,0 +1,52 @@
<!--
~~~~~~licensing~~~~~~
atlasmap-entaxy-services
==========
Copyright (C) 2020 - 2024 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>

View File

@ -0,0 +1,229 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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~~~~~~
*/
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
/* JavaCCOptions:KEEP_LINE_COL=null */
/**
* 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.
*/
package io.atlasmap.expression.parser;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* You can modify this class to customize your error reporting
* mechanisms so long as you retain the public fields.
*/
public class ParseException extends Exception {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set.
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super();
}
/** Constructor with message. */
public ParseException(String message) {
super(message);
}
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* It uses "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser) the correct error message
* gets displayed.
*/
private static String initialise(Token currentToken,
int[][] expectedTokenSequences,
String[] tokenImage) {
String eol = System.getProperty("line.separator", "\n");
StringBuffer expected = new StringBuffer();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected.append("...");
}
expected.append(eol).append(" ");
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += " " + tokenImage[tok.kind];
retval += " \"";
retval += add_escapes(tok.image);
retval += " \"";
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected.toString();
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
static String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}
/* JavaCC - OriginalChecksum=57c0545e6eb1c4d2e2de50c9c12b8028 (do not edit this line) */

View File

@ -0,0 +1,132 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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~~~~~~
*/
/* Generated By:JavaCC: Do not edit this line. ParserConstants.java */
/**
* 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.
*/
package io.atlasmap.expression.parser;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface ParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int LINE_COMMENT = 6;
/** RegularExpression Id. */
int BLOCK_COMMENT = 7;
/** RegularExpression Id. */
int AND = 8;
/** RegularExpression Id. */
int OR = 9;
/** RegularExpression Id. */
int TRUE = 10;
/** RegularExpression Id. */
int FALSE = 11;
/** RegularExpression Id. */
int NULL = 12;
/** RegularExpression Id. */
int DECIMAL_LITERAL = 13;
/** RegularExpression Id. */
int ZERO = 14;
/** RegularExpression Id. */
int HEX_LITERAL = 15;
/** RegularExpression Id. */
int OCTAL_LITERAL = 16;
/** RegularExpression Id. */
int FLOATING_POINT_LITERAL = 17;
/** RegularExpression Id. */
int EXPONENT = 18;
/** RegularExpression Id. */
int STRING_LITERAL = 19;
/** RegularExpression Id. */
int ID = 20;
/** RegularExpression Id. */
int VARIABLE = 21;
/** Lexical state. */
int DEFAULT = 0;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\" \"",
"\"\\t\"",
"\"\\n\"",
"\"\\r\"",
"\"\\f\"",
"<LINE_COMMENT>",
"<BLOCK_COMMENT>",
"\"&&\"",
"\"||\"",
"\"TRUE\"",
"\"FALSE\"",
"\"NULL\"",
"<DECIMAL_LITERAL>",
"\"0\"",
"<HEX_LITERAL>",
"<OCTAL_LITERAL>",
"<FLOATING_POINT_LITERAL>",
"<EXPONENT>",
"<STRING_LITERAL>",
"<ID>",
"<VARIABLE>",
"\"==\"",
"\"!=\"",
"\">\"",
"\">=\"",
"\"<\"",
"\"<=\"",
"\"+\"",
"\"-\"",
"\"*\"",
"\"/\"",
"\"%\"",
"\"!\"",
"\"(\"",
"\")\"",
"\",\"",
};
}

View File

@ -0,0 +1,912 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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~~~~~~
*/
/* Generated By:JavaCC: Do not edit this line. ParserTokenManager.java */
/**
* 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.
*/
package io.atlasmap.expression.parser;
import java.io.*;
import java.util.*;
import io.atlasmap.expression.*;
import io.atlasmap.expression.internal.*;
import static io.atlasmap.expression.internal.BooleanExpression.asBooleanExpression;
/** Token Manager. */
public class ParserTokenManager implements ParserConstants
{
/** Debug output. */
public java.io.PrintStream debugStream = System.out;
/** Set debug output. */
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
private int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
case 9:
jjmatchedKind = 2;
return jjMoveNfa_0(5, 0);
case 10:
jjmatchedKind = 3;
return jjMoveNfa_0(5, 0);
case 12:
jjmatchedKind = 5;
return jjMoveNfa_0(5, 0);
case 13:
jjmatchedKind = 4;
return jjMoveNfa_0(5, 0);
case 32:
jjmatchedKind = 1;
return jjMoveNfa_0(5, 0);
case 33:
jjmatchedKind = 33;
return jjMoveStringLiteralDfa1_0(0x800000L);
case 37:
jjmatchedKind = 32;
return jjMoveNfa_0(5, 0);
case 38:
return jjMoveStringLiteralDfa1_0(0x100L);
case 40:
jjmatchedKind = 34;
return jjMoveNfa_0(5, 0);
case 41:
jjmatchedKind = 35;
return jjMoveNfa_0(5, 0);
case 42:
jjmatchedKind = 30;
return jjMoveNfa_0(5, 0);
case 43:
jjmatchedKind = 28;
return jjMoveNfa_0(5, 0);
case 44:
jjmatchedKind = 36;
return jjMoveNfa_0(5, 0);
case 45:
jjmatchedKind = 29;
return jjMoveNfa_0(5, 0);
case 47:
jjmatchedKind = 31;
return jjMoveNfa_0(5, 0);
case 48:
jjmatchedKind = 14;
return jjMoveNfa_0(5, 0);
case 60:
jjmatchedKind = 26;
return jjMoveStringLiteralDfa1_0(0x8000000L);
case 61:
return jjMoveStringLiteralDfa1_0(0x400000L);
case 62:
jjmatchedKind = 24;
return jjMoveStringLiteralDfa1_0(0x2000000L);
case 70:
return jjMoveStringLiteralDfa1_0(0x800L);
case 78:
return jjMoveStringLiteralDfa1_0(0x1000L);
case 84:
return jjMoveStringLiteralDfa1_0(0x400L);
case 102:
return jjMoveStringLiteralDfa1_0(0x800L);
case 110:
return jjMoveStringLiteralDfa1_0(0x1000L);
case 116:
return jjMoveStringLiteralDfa1_0(0x400L);
case 124:
return jjMoveStringLiteralDfa1_0(0x200L);
default :
return jjMoveNfa_0(5, 0);
}
}
private int jjMoveStringLiteralDfa1_0(long active0)
{
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
return jjMoveNfa_0(5, 0);
}
switch(curChar)
{
case 38:
if ((active0 & 0x100L) != 0L)
{
jjmatchedKind = 8;
jjmatchedPos = 1;
}
break;
case 61:
if ((active0 & 0x400000L) != 0L)
{
jjmatchedKind = 22;
jjmatchedPos = 1;
}
else if ((active0 & 0x800000L) != 0L)
{
jjmatchedKind = 23;
jjmatchedPos = 1;
}
else if ((active0 & 0x2000000L) != 0L)
{
jjmatchedKind = 25;
jjmatchedPos = 1;
}
else if ((active0 & 0x8000000L) != 0L)
{
jjmatchedKind = 27;
jjmatchedPos = 1;
}
break;
case 65:
return jjMoveStringLiteralDfa2_0(active0, 0x800L);
case 82:
return jjMoveStringLiteralDfa2_0(active0, 0x400L);
case 85:
return jjMoveStringLiteralDfa2_0(active0, 0x1000L);
case 97:
return jjMoveStringLiteralDfa2_0(active0, 0x800L);
case 114:
return jjMoveStringLiteralDfa2_0(active0, 0x400L);
case 117:
return jjMoveStringLiteralDfa2_0(active0, 0x1000L);
case 124:
if ((active0 & 0x200L) != 0L)
{
jjmatchedKind = 9;
jjmatchedPos = 1;
}
break;
default :
break;
}
return jjMoveNfa_0(5, 1);
}
private int jjMoveStringLiteralDfa2_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjMoveNfa_0(5, 1);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
return jjMoveNfa_0(5, 1);
}
switch(curChar)
{
case 76:
return jjMoveStringLiteralDfa3_0(active0, 0x1800L);
case 85:
return jjMoveStringLiteralDfa3_0(active0, 0x400L);
case 108:
return jjMoveStringLiteralDfa3_0(active0, 0x1800L);
case 117:
return jjMoveStringLiteralDfa3_0(active0, 0x400L);
default :
break;
}
return jjMoveNfa_0(5, 2);
}
private int jjMoveStringLiteralDfa3_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjMoveNfa_0(5, 2);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
return jjMoveNfa_0(5, 2);
}
switch(curChar)
{
case 69:
if ((active0 & 0x400L) != 0L)
{
jjmatchedKind = 10;
jjmatchedPos = 3;
}
break;
case 76:
if ((active0 & 0x1000L) != 0L)
{
jjmatchedKind = 12;
jjmatchedPos = 3;
}
break;
case 83:
return jjMoveStringLiteralDfa4_0(active0, 0x800L);
case 101:
if ((active0 & 0x400L) != 0L)
{
jjmatchedKind = 10;
jjmatchedPos = 3;
}
break;
case 108:
if ((active0 & 0x1000L) != 0L)
{
jjmatchedKind = 12;
jjmatchedPos = 3;
}
break;
case 115:
return jjMoveStringLiteralDfa4_0(active0, 0x800L);
default :
break;
}
return jjMoveNfa_0(5, 3);
}
private int jjMoveStringLiteralDfa4_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjMoveNfa_0(5, 3);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
return jjMoveNfa_0(5, 3);
}
switch(curChar)
{
case 69:
if ((active0 & 0x800L) != 0L)
{
jjmatchedKind = 11;
jjmatchedPos = 4;
}
break;
case 101:
if ((active0 & 0x800L) != 0L)
{
jjmatchedKind = 11;
jjmatchedPos = 4;
}
break;
default :
break;
}
return jjMoveNfa_0(5, 4);
}
static final long[] jjbitVec0 = {
0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
};
static final long[] jjbitVec2 = {
0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private int jjMoveNfa_0(int startState, int curPos)
{
int strKind = jjmatchedKind;
int strPos = jjmatchedPos;
int seenUpto;
input_stream.backup(seenUpto = curPos + 1);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { throw new Error("Internal Error"); }
curPos = 0;
int startsAt = 0;
jjnewStateCnt = 49;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 5:
if ((0x3ff000000000000L & l) != 0L)
jjCheckNAddStates(0, 3);
else if (curChar == 36)
jjstateSet[jjnewStateCnt++] = 28;
else if (curChar == 39)
jjCheckNAddStates(4, 6);
else if (curChar == 46)
jjCheckNAdd(17);
else if (curChar == 47)
jjstateSet[jjnewStateCnt++] = 6;
else if (curChar == 45)
jjstateSet[jjnewStateCnt++] = 0;
if ((0x3fe000000000000L & l) != 0L)
{
if (kind > 13)
kind = 13;
jjCheckNAddTwoStates(14, 15);
}
else if (curChar == 48)
{
if (kind > 16)
kind = 16;
jjCheckNAddTwoStates(46, 48);
}
break;
case 0:
if (curChar == 45)
jjCheckNAddStates(7, 9);
break;
case 1:
if ((0xffffffffffffdbffL & l) != 0L)
jjCheckNAddStates(7, 9);
break;
case 2:
if ((0x2400L & l) != 0L && kind > 6)
kind = 6;
break;
case 3:
if (curChar == 10 && kind > 6)
kind = 6;
break;
case 4:
if (curChar == 13)
jjstateSet[jjnewStateCnt++] = 3;
break;
case 6:
if (curChar == 42)
jjCheckNAddTwoStates(7, 8);
break;
case 7:
if ((0xfffffbffffffffffL & l) != 0L)
jjCheckNAddTwoStates(7, 8);
break;
case 8:
if (curChar == 42)
jjCheckNAddStates(10, 12);
break;
case 9:
if ((0xffff7bffffffffffL & l) != 0L)
jjCheckNAddTwoStates(10, 8);
break;
case 10:
if ((0xfffffbffffffffffL & l) != 0L)
jjCheckNAddTwoStates(10, 8);
break;
case 11:
if (curChar == 47 && kind > 7)
kind = 7;
break;
case 12:
if (curChar == 47)
jjstateSet[jjnewStateCnt++] = 6;
break;
case 13:
if ((0x3fe000000000000L & l) == 0L)
break;
if (kind > 13)
kind = 13;
jjCheckNAddTwoStates(14, 15);
break;
case 14:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 13)
kind = 13;
jjCheckNAddTwoStates(14, 15);
break;
case 16:
if (curChar == 46)
jjCheckNAdd(17);
break;
case 17:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAddTwoStates(17, 18);
break;
case 19:
if ((0x280000000000L & l) != 0L)
jjCheckNAdd(20);
break;
case 20:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAdd(20);
break;
case 21:
case 22:
if (curChar == 39)
jjCheckNAddStates(4, 6);
break;
case 23:
if (curChar == 39)
jjstateSet[jjnewStateCnt++] = 22;
break;
case 24:
if ((0xffffff7fffffffffL & l) != 0L)
jjCheckNAddStates(4, 6);
break;
case 25:
if (curChar == 39 && kind > 19)
kind = 19;
break;
case 27:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 20)
kind = 20;
jjstateSet[jjnewStateCnt++] = 27;
break;
case 31:
jjAddStates(13, 15);
break;
case 33:
if (curChar == 36)
jjstateSet[jjnewStateCnt++] = 28;
break;
case 34:
if ((0x3ff000000000000L & l) != 0L)
jjCheckNAddStates(0, 3);
break;
case 35:
if ((0x3ff000000000000L & l) != 0L)
jjCheckNAddTwoStates(35, 36);
break;
case 36:
if (curChar != 46)
break;
if (kind > 17)
kind = 17;
jjCheckNAddTwoStates(37, 38);
break;
case 37:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAddTwoStates(37, 38);
break;
case 39:
if ((0x280000000000L & l) != 0L)
jjCheckNAdd(40);
break;
case 40:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAdd(40);
break;
case 41:
if ((0x3ff000000000000L & l) != 0L)
jjCheckNAddTwoStates(41, 42);
break;
case 43:
if ((0x280000000000L & l) != 0L)
jjCheckNAdd(44);
break;
case 44:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 17)
kind = 17;
jjCheckNAdd(44);
break;
case 45:
if (curChar != 48)
break;
if (kind > 16)
kind = 16;
jjCheckNAddTwoStates(46, 48);
break;
case 47:
if ((0x3ff000000000000L & l) == 0L)
break;
if (kind > 15)
kind = 15;
jjstateSet[jjnewStateCnt++] = 47;
break;
case 48:
if ((0xff000000000000L & l) == 0L)
break;
if (kind > 16)
kind = 16;
jjCheckNAdd(48);
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 5:
case 27:
if ((0x7fffffe87fffffeL & l) == 0L)
break;
if (kind > 20)
kind = 20;
jjCheckNAdd(27);
break;
case 1:
jjAddStates(7, 9);
break;
case 7:
jjCheckNAddTwoStates(7, 8);
break;
case 9:
case 10:
jjCheckNAddTwoStates(10, 8);
break;
case 15:
if ((0x100000001000L & l) != 0L && kind > 13)
kind = 13;
break;
case 18:
if ((0x2000000020L & l) != 0L)
jjAddStates(16, 17);
break;
case 24:
jjAddStates(4, 6);
break;
case 28:
if (curChar == 123)
jjCheckNAddTwoStates(30, 31);
break;
case 29:
if (curChar == 125)
jjCheckNAddStates(13, 15);
break;
case 30:
if (curChar == 92)
jjstateSet[jjnewStateCnt++] = 29;
break;
case 31:
if ((0xdfffffffffffffffL & l) != 0L)
jjCheckNAddStates(13, 15);
break;
case 32:
if (curChar == 125 && kind > 21)
kind = 21;
break;
case 38:
if ((0x2000000020L & l) != 0L)
jjAddStates(18, 19);
break;
case 42:
if ((0x2000000020L & l) != 0L)
jjAddStates(20, 21);
break;
case 46:
if ((0x100000001000000L & l) != 0L)
jjCheckNAdd(47);
break;
case 47:
if ((0x7e0000007eL & l) == 0L)
break;
if (kind > 15)
kind = 15;
jjCheckNAdd(47);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int hiByte = (int)(curChar >> 8);
int i1 = hiByte >> 6;
long l1 = 1L << (hiByte & 077);
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 1:
if (jjCanMove_0(hiByte, i1, i2, l1, l2))
jjAddStates(7, 9);
break;
case 7:
if (jjCanMove_0(hiByte, i1, i2, l1, l2))
jjCheckNAddTwoStates(7, 8);
break;
case 9:
case 10:
if (jjCanMove_0(hiByte, i1, i2, l1, l2))
jjCheckNAddTwoStates(10, 8);
break;
case 24:
if (jjCanMove_0(hiByte, i1, i2, l1, l2))
jjAddStates(4, 6);
break;
case 31:
if (jjCanMove_0(hiByte, i1, i2, l1, l2))
jjAddStates(13, 15);
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 49 - (jjnewStateCnt = startsAt)))
break;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { break; }
}
if (jjmatchedPos > strPos)
return curPos;
int toRet = Math.max(curPos, seenUpto);
if (curPos < toRet)
for (i = toRet - Math.min(curPos, seenUpto); i-- > 0; )
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { throw new Error("Internal Error : Please send a bug report."); }
if (jjmatchedPos < strPos)
{
jjmatchedKind = strKind;
jjmatchedPos = strPos;
}
else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
jjmatchedKind = strKind;
return toRet;
}
static final int[] jjnextStates = {
35, 36, 41, 42, 23, 24, 25, 1, 2, 4, 8, 9, 11, 30, 31, 32,
19, 20, 39, 40, 43, 44,
};
private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
{
switch(hiByte)
{
case 0:
return ((jjbitVec2[i2] & l2) != 0L);
default :
if ((jjbitVec0[i1] & l1) != 0L)
return true;
return false;
}
}
/** Token literal values. */
public static final String[] jjstrLiteralImages = {
"", null, null, null, null, null, null, null, "\46\46", "\174\174", null, null,
null, null, "\60", null, null, null, null, null, null, null, "\75\75", "\41\75",
"\76", "\76\75", "\74", "\74\75", "\53", "\55", "\52", "\57", "\45", "\41", "\50",
"\51", "\54", };
/** Lexer state names. */
public static final String[] lexStateNames = {
"DEFAULT",
};
static final long[] jjtoToken = {
0x1ffffbff01L,
};
static final long[] jjtoSkip = {
0xfeL,
};
static final long[] jjtoSpecial = {
0x3eL,
};
protected SimpleCharStream input_stream;
private final int[] jjrounds = new int[49];
private final int[] jjstateSet = new int[98];
protected char curChar;
/** Constructor. */
public ParserTokenManager(SimpleCharStream stream){
if (SimpleCharStream.staticFlag)
throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
input_stream = stream;
}
/** Constructor. */
public ParserTokenManager(SimpleCharStream stream, int lexState){
this(stream);
SwitchTo(lexState);
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream)
{
jjmatchedPos = jjnewStateCnt = 0;
curLexState = defaultLexState;
input_stream = stream;
ReInitRounds();
}
private void ReInitRounds()
{
int i;
jjround = 0x80000001;
for (i = 49; i-- > 0;)
jjrounds[i] = 0x80000000;
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream, int lexState)
{
ReInit(stream);
SwitchTo(lexState);
}
/** Switch to specified lex state. */
public void SwitchTo(int lexState)
{
if (lexState >= 1 || lexState < 0)
throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
else
curLexState = lexState;
}
protected Token jjFillToken()
{
final Token t;
final String curTokenImage;
final int beginLine;
final int endLine;
final int beginColumn;
final int endColumn;
String im = jjstrLiteralImages[jjmatchedKind];
curTokenImage = (im == null) ? input_stream.GetImage() : im;
beginLine = input_stream.getBeginLine();
beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind, curTokenImage);
t.beginLine = beginLine;
t.endLine = endLine;
t.beginColumn = beginColumn;
t.endColumn = endColumn;
return t;
}
int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;
/** Get the next Token. */
public Token getNextToken()
{
Token specialToken = null;
Token matchedToken;
int curPos = 0;
EOFLoop :
for (;;)
{
try
{
curChar = input_stream.BeginToken();
}
catch(java.io.IOException e)
{
jjmatchedKind = 0;
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
return matchedToken;
}
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
if (jjmatchedKind != 0x7fffffff)
{
if (jjmatchedPos + 1 < curPos)
input_stream.backup(curPos - jjmatchedPos - 1);
if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
matchedToken.specialToken = specialToken;
return matchedToken;
}
else
{
if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
{
matchedToken = jjFillToken();
if (specialToken == null)
specialToken = matchedToken;
else
{
matchedToken.specialToken = specialToken;
specialToken = (specialToken.next = matchedToken);
}
}
continue EOFLoop;
}
}
int error_line = input_stream.getEndLine();
int error_column = input_stream.getEndColumn();
String error_after = null;
boolean EOFSeen = false;
try { input_stream.readChar(); input_stream.backup(1); }
catch (java.io.IOException e1) {
EOFSeen = true;
error_after = curPos <= 1 ? "" : input_stream.GetImage();
if (curChar == '\n' || curChar == '\r') {
error_line++;
error_column = 0;
}
else
error_column++;
}
if (!EOFSeen) {
input_stream.backup(1);
error_after = curPos <= 1 ? "" : input_stream.GetImage();
}
throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
}
}
private void jjCheckNAdd(int state)
{
if (jjrounds[state] != jjround)
{
jjstateSet[jjnewStateCnt++] = state;
jjrounds[state] = jjround;
}
}
private void jjAddStates(int start, int end)
{
do {
jjstateSet[jjnewStateCnt++] = jjnextStates[start];
} while (start++ != end);
}
private void jjCheckNAddTwoStates(int state1, int state2)
{
jjCheckNAdd(state1);
jjCheckNAdd(state2);
}
private void jjCheckNAddStates(int start, int end)
{
do {
jjCheckNAdd(jjnextStates[start]);
} while (start++ != end);
}
}

View File

@ -0,0 +1,513 @@
/*-
* ~~~~~~licensing~~~~~~
* atlasmap-entaxy-services
* ==========
* Copyright (C) 2020 - 2024 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~~~~~~
*/
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
/**
* 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.
*/
package io.atlasmap.expression.parser;
/**
* An implementation of interface CharStream, where the stream is assumed to
* contain only ASCII characters (without unicode processing).
*/
public class SimpleCharStream
{
/** Whether parser is static. */
public static final boolean staticFlag = false;
int bufsize;
int available;
int tokenBegin;
/** Position in buffer. */
public int bufpos = -1;
protected int bufline[];
protected int bufcolumn[];
protected int column = 0;
protected int line = 1;
protected boolean prevCharIsCR = false;
protected boolean prevCharIsLF = false;
protected java.io.Reader inputStream;
protected char[] buffer;
protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected int tabSize = 8;
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
int newbufcolumn[] = new int[bufsize + 2048];
try
{
if (wrapAround)
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
}
else
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
}
}
catch (Throwable t)
{
throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize;
tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{
if (maxNextCharInd == available)
{
if (available == bufsize)
{
if (tokenBegin > 2048)
{
bufpos = maxNextCharInd = 0;
available = tokenBegin;
}
else if (tokenBegin < 0)
bufpos = maxNextCharInd = 0;
else
ExpandBuff(false);
}
else if (available > tokenBegin)
available = bufsize;
else if ((tokenBegin - available) < 2048)
ExpandBuff(true);
else
available = tokenBegin;
}
int i;
try {
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
--bufpos;
backup(0);
if (tokenBegin == -1)
tokenBegin = bufpos;
throw e;
}
}
/** Start. */
public char BeginToken() throws java.io.IOException
{
tokenBegin = -1;
char c = readChar();
tokenBegin = bufpos;
return c;
}
protected void UpdateLineColumn(char c)
{
column++;
if (prevCharIsLF)
{
prevCharIsLF = false;
line += (column = 1);
}
else if (prevCharIsCR)
{
prevCharIsCR = false;
if (c == '\n')
{
prevCharIsLF = true;
}
else
line += (column = 1);
}
switch (c)
{
case '\r' :
prevCharIsCR = true;
break;
case '\n' :
prevCharIsLF = true;
break;
case '\t' :
column--;
column += (tabSize - (column % tabSize));
break;
default :
break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
/** Read a character. */
public char readChar() throws java.io.IOException
{
if (inBuf > 0)
{
--inBuf;
if (++bufpos == bufsize)
bufpos = 0;
return buffer[bufpos];
}
if (++bufpos >= maxNextCharInd)
FillBuff();
char c = buffer[bufpos];
UpdateLineColumn(c);
return c;
}
@Deprecated
/**
* @deprecated
* @see #getEndColumn
*/
public int getColumn() {
return bufcolumn[bufpos];
}
@Deprecated
/**
* @deprecated
* @see #getEndLine
*/
public int getLine() {
return bufline[bufpos];
}
/** Get token end column number. */
public int getEndColumn() {
return bufcolumn[bufpos];
}
/** Get token end line number. */
public int getEndLine() {
return bufline[bufpos];
}
/** Get token beginning column number. */
public int getBeginColumn() {
return bufcolumn[tokenBegin];
}
/** Get token beginning line number. */
public int getBeginLine() {
return bufline[tokenBegin];
}
/** Backup a number of characters. */
public void backup(int amount) {
inBuf += amount;
if ((bufpos -= amount) < 0)
bufpos += bufsize;
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
if (buffer == null || buffersize != buffer.length)
{
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
prevCharIsLF = prevCharIsCR = false;
tokenBegin = inBuf = maxNextCharInd = 0;
bufpos = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Get token literal value. */
public String GetImage()
{
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
new String(buffer, 0, bufpos + 1);
}
/** Get the suffix. */
public char[] GetSuffix(int len)
{
char[] ret = new char[len];
if ((bufpos + 1) >= len)
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
else
{
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len - bufpos - 1);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
return ret;
}
/** Reset buffer when finished. */
public void Done()
{
buffer = null;
bufline = null;
bufcolumn = null;
}
/**
* Method to adjust line and column numbers for the start of a token.
*/
public void adjustBeginLineColumn(int newLine, int newCol)
{
int start = tokenBegin;
int len;
if (bufpos >= tokenBegin)
{
len = bufpos - tokenBegin + inBuf + 1;
}
else
{
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=3d9ae710b8421aa93323fa2dcb67d5b4 (do not edit this line) */

Some files were not shown because too many files have changed in this diff Show More