Skip to content

Commit

Permalink
Excel mapper (#152)
Browse files Browse the repository at this point in the history
* [Excel Mapper] Added support to parse Excel sheet to a POJO class

* [Excel Mapper] Minor code changes

* [Excel Mapper] Minor code changes

* [Excel Mapper] Read data stream

* [Excel Mapper] Early exist for non xlsx files

* [Snapshot] Using ReflectionHelper

* [Excel] Sonar checks
  • Loading branch information
RameshBabuPrudhvi authored Jun 28, 2022
1 parent 24de790 commit cd5e1f6
Show file tree
Hide file tree
Showing 16 changed files with 690 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.commons.helper;

import lombok.experimental.UtilityClass;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

@UtilityClass
public class ReflectionHelper {
@SuppressWarnings("all")
public static <T> T newInstance(Class<T> clazz) {
try {
Constructor<T> constructor = clazz.getDeclaredConstructor();
if ((!Modifier.isPublic(constructor.getModifiers()) ||
!Modifier.isPublic(constructor.getDeclaringClass().getModifiers())) &&
!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return constructor.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(e);
}

}

@SuppressWarnings("squid:S3011")
public static void setField(Object object, String fieldName, Object value) {
try {
Class<?> clazz = object == null ? Object.class : object.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}

}

@SuppressWarnings("squid:S3011")
public static <T> Method getDeclaredMethod(Class<T> clazz, String name, Class<?>... param) {
try {
Method method = clazz.getDeclaredMethod(name, param);
method.setAccessible(true);
return method;
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,7 @@
String rootFolder() default "";

boolean streamLoader() default false;

String sheetName() default "";
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel;

import io.github.selcukes.databind.exception.DataMapperException;
import io.github.selcukes.databind.utils.DataFileHelper;
import io.github.selcukes.excel.parser.ExcelData;
import lombok.experimental.UtilityClass;

import java.util.stream.Stream;

@UtilityClass
public class ExcelMapper {
/**
* Parses the Excel file to an Entity Class.
*
* @param <T> the Class type.
* @param entityClass the entity class
* @return the Stream of Entity class objects
*/
public static <T> Stream<T> parse(final Class<T> entityClass) {
final DataFileHelper<T> dataFile = DataFileHelper.getInstance(entityClass);
final String fileName = dataFile.getFileName();
int extensionIndex = fileName.lastIndexOf('.');
final String extension = fileName.substring(extensionIndex + 1);
if (!extension.equalsIgnoreCase("xlsx")) {
throw new DataMapperException(String.format("File [%s] not found.",
fileName.substring(0, extensionIndex) + ".xlsx"));
}
ExcelData<T> excelMapper = new ExcelData<>(entityClass);
return excelMapper.parse(dataFile.getPath());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.annotation;


import io.github.selcukes.excel.converters.StringConverter;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String name();

String format() default "";

Class<?> converter() default StringConverter.class;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.converters;

import java.lang.reflect.Type;

import static java.lang.Boolean.parseBoolean;

public class BooleanConverter extends DefaultConverter<Boolean> {
@Override
public Boolean convert(final String value) {
return parseBoolean(value);
}

@Override
public Type getType() {
return Boolean.TYPE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.converters;

import java.lang.reflect.Type;

public interface Converter<T> {
T convert(String value);

Type getType();

default T convert(final String value, final String format) {
return convert(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.converters;

import java.lang.reflect.Type;

public abstract class DefaultConverter<T> implements Converter<T> {
private final Type type;

@SafeVarargs
protected DefaultConverter(final T... values) {
this.type = values.getClass().getComponentType();
}

@Override
public Type getType() {
return type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.converters;


import lombok.SneakyThrows;

import java.lang.reflect.Type;
import java.text.NumberFormat;
import java.util.Locale;

public class DoubleConverter extends DefaultConverter<Double> {
@SneakyThrows
@Override
public Double convert(final String value) {
return NumberFormat.getInstance(Locale.getDefault()).parse(value).doubleValue();
}

@Override
public Type getType() {
return Double.TYPE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.converters;

import java.lang.reflect.Type;

import static java.lang.Integer.parseInt;

public class IntegerConverter extends DefaultConverter<Integer> {
@Override
public Integer convert(final String value) {
return parseInt(value);
}

@Override
public Type getType() {
return Integer.TYPE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* 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.github.selcukes.excel.converters;

import java.time.LocalDate;

import static java.time.LocalDate.parse;
import static java.time.format.DateTimeFormatter.ofPattern;
import static java.util.Optional.ofNullable;

public class LocalDateConverter extends DefaultConverter<LocalDate> {
private static final String DEFAULT_FORMAT = "yyyy-MM-dd";

@Override
public LocalDate convert(final String value) {
return convert(value, DEFAULT_FORMAT);
}

@Override
public LocalDate convert(final String value, final String format) {
return parse(value, ofPattern(ofNullable(format).filter(f -> !f.isEmpty()).orElse(DEFAULT_FORMAT)));
}
}
Loading

0 comments on commit cd5e1f6

Please sign in to comment.