/** * Copyright 2011-2017 Asakusa Framework Team. * * 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 com.asakusafw.dmdl.directio.text; import static com.asakusafw.dmdl.directio.text.TextFormatConstants.*; import java.nio.charset.Charset; import java.util.Map; import java.util.Optional; import com.asakusafw.dmdl.directio.util.ClassName; import com.asakusafw.dmdl.directio.util.CodecNames; import com.asakusafw.dmdl.directio.util.Value; import com.asakusafw.dmdl.model.AstAttribute; import com.asakusafw.dmdl.model.AstAttributeElement; import com.asakusafw.dmdl.semantics.DmdlSemantics; import com.asakusafw.runtime.io.text.LineSeparator; import com.asakusafw.runtime.io.text.driver.ErrorAction; import com.asakusafw.runtime.io.text.driver.HeaderType; /** * Settings of formatted text file. * @since 0.9.1 */ public class TextFormatSettings { private Value<Charset> charset = Value.undefined(); private Value<HeaderType> headerType = Value.undefined(); private Value<ClassName> compressionType = Value.undefined(); private Value<LineSeparator> lineSeparator = Value.undefined(); private Value<Character> fieldSeparator = Value.undefined(); private Value<ErrorAction> lessInputAction = Value.undefined(); private Value<ErrorAction> moreInputAction = Value.undefined(); private Value<ClassName> inputTransformerClass = Value.undefined(); private Value<ClassName> outputTransformerClass = Value.undefined(); /** * Returns the charset name. * @return the charset name */ public Value<Charset> getCharset() { return charset; } /** * Returns the header type. * @return the header type */ public Value<HeaderType> getHeaderType() { return headerType; } /** * Returns the compression type. * @return the compression type */ public Value<ClassName> getCompressionType() { return compressionType; } /** * Returns the line separator. * @return the line separator */ public Value<LineSeparator> getLineSeparator() { return lineSeparator; } /** * Returns the field separator. * @return the field separator */ public Value<Character> getFieldSeparator() { return fieldSeparator; } /** * Returns the error action type for less input fields. * @return the error action type for less input fields */ public Value<ErrorAction> getLessInputAction() { return lessInputAction; } /** * Returns the error action type for extra input fields. * @return the error action type for extra input fields */ public Value<ErrorAction> getMoreInputAction() { return moreInputAction; } /** * Returns the input transformer class. * @return the input transformer class */ public Value<ClassName> getInputTransformerClass() { return inputTransformerClass; } /** * Returns the output transformer class. * @return the output transformer class */ public Value<ClassName> getOutputTransformerClass() { return outputTransformerClass; } /** * Consumes attribute elements about escape settings, and returns corresponding {@link EscapeSettings}. * @param environment the current environment * @param attribute the attribute * @param elements the element map to be consumed * @return corresponded {@link EscapeSettings}. */ public static TextFormatSettings consume( DmdlSemantics environment, AstAttribute attribute, Map<String, AstAttributeElement> elements) { AttributeAnalyzer analyzer = new AttributeAnalyzer(environment, attribute); TextFormatSettings settings = new TextFormatSettings(); consumeCharset(settings, analyzer, elements.remove(ELEMENT_CHARSET_NAME)); consumeHeaderType(settings, analyzer, elements.remove(ELEMENT_HEADER_TYPE)); consumeCompressionType(settings, analyzer, elements.remove(ELEMENT_COMPRESSION_TYPE)); consumeLineSeparator(settings, analyzer, elements.remove(ELEMENT_LINE_SEPARATOR)); consumeFieldSeparator(settings, analyzer, elements.remove(ELEMENT_FIELD_SEPARATOR)); consumeLessInputAction(settings, analyzer, elements.remove(ELEMENT_LESS_INPUT_ACTION)); consumeMoreInputAction(settings, analyzer, elements.remove(ELEMENT_MORE_INPUT_ACTION)); consumeInputTransformerClass(settings, analyzer, elements.remove(ELEMENT_INPUT_TRANSFORMER)); consumeOutputTransformerClass(settings, analyzer, elements.remove(ELEMENT_OUTPUT_TRANSFORMER)); return settings; } private static void consumeCharset( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.charset = analyzer.toCharset(element); } } private static void consumeHeaderType( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.headerType = analyzer.toEnumConstant(element, HeaderType.class); } } private static void consumeCompressionType( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.compressionType = analyzer.toClassName( element, s -> Optional.of(CodecNames.resolveCodecName(s))); } } private static void consumeLineSeparator( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.lineSeparator = analyzer.toEnumConstant(element, LineSeparator.class); } } private static void consumeFieldSeparator( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.fieldSeparator = analyzer.toCharacter(element); } } private static void consumeLessInputAction( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.lessInputAction = analyzer.toEnumConstant(element, ErrorAction.class); } } private static void consumeMoreInputAction( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.moreInputAction = analyzer.toEnumConstant(element, ErrorAction.class); } } private static void consumeInputTransformerClass( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.inputTransformerClass = analyzer.toClassName(element); } } private static void consumeOutputTransformerClass( TextFormatSettings settings, AttributeAnalyzer analyzer, AstAttributeElement element) { if (element != null) { settings.outputTransformerClass = analyzer.toClassName(element); } } /** * Verifies this settings. * @param environment the current environment * @param attribute the original attribute * @return {@code true} if the settings seems valid, otherwise {@code false} */ public boolean verify(DmdlSemantics environment, AstAttribute attribute) { AttributeAnalyzer analyzer = new AttributeAnalyzer(environment, attribute); if (fieldSeparator.isPresent()) { char c = fieldSeparator.getEntity(); if (c == '\r' || c == '\n') { analyzer.error(fieldSeparator.getDeclaration(), Messages.getString("TextFormatSettings.diagnosticConflictLineSeparator")); //$NON-NLS-1$ } } return analyzer.hasError() == false; } }