<commit_before>/*
 * jETeL/CloverETL - Java based ETL application framework.
 * Copyright (c) Javlin, a.s. (<EMAIL>)
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.jetel.data.parser;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.jetel.exception.ComponentNotReadyException;
import org.jetel.exception.ConfigurationStatus;
import org.jetel.exception.JetelRuntimeException;
import org.jetel.metadata.DataFieldMetadata;
import org.jetel.metadata.DataRecordMetadata;
import org.jetel.util.SpreadsheetUtils;
import org.jetel.util.string.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @author lkrejci (<EMAIL>)
 *         (c) Javlin, a.s. (www.cloveretl.com)
 *
 * @created 18 Aug 2011
 */
public class XLSMapping {
	
	public static final String DEFAULT_VERSION = "1.0";
	public static final String DEFAULT_ENCODING = "UTF-8";
	
	public static final int DEFAULT_SKIP = 0;
	public static final SpreadsheetMappingMode DEFAULT_AUTO_MAPPING_MODE = SpreadsheetMappingMode.AUTO;
	
	public static final int UNDEFINED = -1;
	public static final char ESCAPE_START = '[';
	public static final char ESCAPE_END = ']';
	
	private static final String XPATH_GLOBAL_ATTRIBUTES = "/mapping/globalAttributes/";
	private static final String XPATH_STEP_ATTRIBUTE = XPATH_GLOBAL_ATTRIBUTES + "step/text()";
	private static final String XPATH_ORIENTATION_ATTRIBUTE = XPATH_GLOBAL_ATTRIBUTES + "orientation/text()";
	private static final String XPATH_WRITE_HEADER_ATTRIBUTE = XPATH_GLOBAL_ATTRIBUTES + "writeHeader/text()";

	private static final String XML_HEADER_GROUP = "headerGroup";
	private static final String XML_HEADER_GROUP_CLOVER_FIELD = "cloverField";
	private static final String XML_HEADER_GROUP_SKIP = "skip";
	private static final String XML_HEADER_GROUP_AUTO_MAPPING_TYPE = "autoMappingType";
	private static final String XML_HEADER_RANGES = "headerRanges";
	private static final String XML_HEADER_RANGE_BEGIN = "begin";
	private static final String XML_HEADER_RANGE_END = "end";

	private static final Pattern HEADER_PATTERN = Pattern.compile("([A-Z]{1,3})([1-9][0-9]{0,6})");
	
	final public static SpreadsheetOrientation HEADER_ON_TOP = SpreadsheetOrientation.VERTICAL;
	
	private static final XLSMapping DEFAULT_MAPPING;
	static {
		List<HeaderGroup> groups = Collections.emptyList();
		DEFAULT_MAPPING = new XLSMapping(1, HEADER_ON_TOP, true, groups);
	}
	
	private final int step;
	private final SpreadsheetOrientation orientation;
	private final boolean writeHeader;
	
	private final List<HeaderGroup> headerGroups;
	private final Stats stats;
	
	public XLSMapping(DataRecordMetadata metaData) {
		this.step = 1;
		this.orientation = HEADER_ON_TOP;
		this.headerGroups = new ArrayList<HeaderGroup> ();
		DataFieldMetadata [] dataFields = metaData.getFields();
		for (int i=0; i<dataFields.length; ++i) {
			DataFieldMetadata dataField = dataFields[i];
			headerGroups.add(new HeaderGroup(0, dataField.getNumber(), SpreadsheetMappingMode.AUTO, Collections.singletonList(new HeaderRange(0, 0, i, i))));
		}
		this.writeHeader = false;
		this.stats = resolveMappingStats();
	}
	
	private XLSMapping(int step, SpreadsheetOrientation orientation, boolean writeHeader, List<HeaderGroup> groups) {
		this.step = step;
		this.orientation = orientation;
		this.headerGroups = groups;
		this.writeHeader = writeHeader;
		this.stats = resolveMappingStats();
	}
	
	public int getStep() {
		return step;
	}

	public SpreadsheetOrientation getOrientation() {
		return orientation;
	}<commit_msg>UPDATE: header should be written by default<commit_after>/*
 * jETeL/CloverETL - Java based ETL application framework.
 * Copyright (c) <NAME>. (<EMAIL>)
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.jetel.data.parser;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.jetel.exception.ComponentNotReadyException;
import org.jetel.exception.ConfigurationStatus;
import org.jetel.exception.JetelRuntimeException;
import org.jetel.metadata.DataFieldMetadata;
import org.jetel.metadata.DataRecordMetadata;
import org.jetel.util.SpreadsheetUtils;
import org.jetel.util.string.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @author lkrejci (<EMAIL>)
 *         (c) Javlin, a.s. (www.cloveretl.com)
 *
 * @created 18 Aug 2011
 */
public class XLSMapping {
	
	public static final String DEFAULT_VERSION = "1.0";
	public static final String DEFAULT_ENCODING = "UTF-8";
	
	public static final int DEFAULT_SKIP = 0;
	public static final SpreadsheetMappingMode DEFAULT_AUTO_MAPPING_MODE = SpreadsheetMappingMode.AUTO;
	
	public static final int UNDEFINED = -1;
	public static final char ESCAPE_START = '[';
	public static final char ESCAPE_END = ']';
	
	private static final String XPATH_GLOBAL_ATTRIBUTES = "/mapping/globalAttributes/";
	private static final String XPATH_STEP_ATTRIBUTE = XPATH_GLOBAL_ATTRIBUTES + "step/text()";
	private static final String XPATH_ORIENTATION_ATTRIBUTE = XPATH_GLOBAL_ATTRIBUTES + "orientation/text()";
	private static final String XPATH_WRITE_HEADER_ATTRIBUTE = XPATH_GLOBAL_ATTRIBUTES + "writeHeader/text()";

	private static final String XML_HEADER_GROUP = "headerGroup";
	private static final String XML_HEADER_GROUP_CLOVER_FIELD = "cloverField";
	private static final String XML_HEADER_GROUP_SKIP = "skip";
	private static final String XML_HEADER_GROUP_AUTO_MAPPING_TYPE = "autoMappingType";
	private static final String XML_HEADER_RANGES = "headerRanges";
	private static final String XML_HEADER_RANGE_BEGIN = "begin";
	private static final String XML_HEADER_RANGE_END = "end";

	private static final Pattern HEADER_PATTERN = Pattern.compile("([A-Z]{1,3})([1-9][0-9]{0,6})");
	
	final public static SpreadsheetOrientation HEADER_ON_TOP = SpreadsheetOrientation.VERTICAL;
	
	private static final XLSMapping DEFAULT_MAPPING;
	static {
		List<HeaderGroup> groups = Collections.emptyList();
		DEFAULT_MAPPING = new XLSMapping(1, HEADER_ON_TOP, true, groups);
	}
	
	private final int step;
	private final SpreadsheetOrientation orientation;
	private final boolean writeHeader;
	
	private final List<HeaderGroup> headerGroups;
	private final Stats stats;
	
	public XLSMapping(DataRecordMetadata metaData) {
		this.step = 1;
		this.orientation = HEADER_ON_TOP;
		this.headerGroups = new ArrayList<HeaderGroup> ();
		DataFieldMetadata [] dataFields = metaData.getFields();
		for (int i=0; i<dataFields.length; ++i) {
			DataFieldMetadata dataField = dataFields[i];
			headerGroups.add(new HeaderGroup(0, dataField.getNumber(), SpreadsheetMappingMode.AUTO, Collections.singletonList(new HeaderRange(0, 0, i, i))));
		}
		this.writeHeader = true;
		this.stats = resolveMappingStats();
	}
	
	private XLSMapping(int step, SpreadsheetOrientation orientation, boolean writeHeader, List<HeaderGroup> groups) {
		this.step = step;
		this.orientation = orientation;
		this.headerGroups = groups;
		this.writeHeader = writeHeader;
		this.stats = resolveMappingStats();
	}
	
	public int getStep() {
		return step;
	}

	public SpreadsheetOrientation getOrientation() {
		return orientation;
	}
{'fraction_non_alphanumeric': 0.09022787928556765, 'fraction_numerical': 0.009238349414904538, 'mean_word_length': 5.289864428663654, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 18}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2766069', 'n_tokens_mistral': 3055, 'n_tokens_neox': 2877, 'n_words': 847}