blob: e6d6e22e649757cf23e34549003bcc944ec69fd1 [file] [log] [blame]
/*
* 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 org.apache.batchee.jsefa;
import net.sf.jsefa.csv.annotation.CsvDataType;
import net.sf.jsefa.csv.annotation.CsvField;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
public class JSefaCsvMapping {
/**
* storage for CsvHeaders
*/
private final List<String> headers = new ArrayList<String>();
private JSefaCsvMapping(Class<?> type) {
calculateHeaders(type);
}
public Iterable<String> getHeader() {
return headers;
}
private void calculateHeaders(Class<?> type) {
SortedMap<Integer, SortedMap<Integer, String>> allHeaders = new TreeMap<Integer, SortedMap<Integer, String>>();
calculateHeaders(type, allHeaders, 0);
for (SortedMap<Integer, String> headerMap : allHeaders.values()) {
for (String header : headerMap.values()) {
headers.add(header);
}
}
}
private void calculateHeaders(Class<?> type, SortedMap<Integer, SortedMap<Integer, String>> allHeaders, int index) {
if (type.getSuperclass() != Object.class) {
// decrement index for inheritance, because index will be the same
// but if we have another object within OR the same positions specified in the @CsvField annotation
// we override the values
calculateHeaders(type.getSuperclass(), allHeaders, index - 1);
}
SortedMap<Integer, String> typeHeaders = new TreeMap<Integer, String>();
for (Field field : type.getDeclaredFields()) {
CsvField fieldAnnotation = field.getAnnotation(CsvField.class);
if (fieldAnnotation == null) {
continue;
}
if (field.getType().getAnnotation(CsvDataType.class) != null) {
calculateHeaders(field.getType(), allHeaders, fieldAnnotation.pos());
} else {
String header = null;
Header headerAnnotation = field.getAnnotation(Header.class);
if (headerAnnotation != null) {
header = headerAnnotation.value();
}
// use field.getName() as default
if (header == null || header.isEmpty()) {
header = field.getName();
}
String previousField = typeHeaders.put(fieldAnnotation.pos(), header);
if (previousField != null) {
throw new IllegalArgumentException(String.format("multiple fields for position %d defined! Fields: %s! Type: %s", fieldAnnotation.pos(),
previousField + ", " + field.getName(),
type.getName()));
}
}
}
allHeaders.put(index, typeHeaders);
}
public static List<JSefaCsvMapping> forTypes(Class<?>... types) {
List<JSefaCsvMapping> mappings = new ArrayList<JSefaCsvMapping>(types.length);
for (Class<?> type : types) {
mappings.add(new JSefaCsvMapping(type));
}
return mappings;
}
}