Java tutorial
/** * Flatworm - A Java Flat File Importer Copyright (C) 2004 James M. Turner * * * 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.blackbear.flatworm; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang.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.SAXException; import com.blackbear.flatworm.errors.FlatwormConfigurationValueException; import com.blackbear.flatworm.errors.FlatwormUnsetFieldValueException; /** * The * <code>ConfigurationReader<code> class is used to initialize Flatworm with an XML configuration file which * describes the format and conversion options to be applied to the input file to produce output beans. */ public class ConfigurationReader { /** * <code>loadConfigurationFile</code> takes an XML configuration file, and * returns a <code>FileFormat</code> object, which can be used to parse an * input file into beans. * * @param xmlFile * An XML file which contains a valid Flatworm configuration * @return A <code>FileFormat</code> object which can parse the specified * format. * @throws FlatwormUnsetFieldValueException * If a required parameter of a tag is not set. * @throws FlatwormConfigurationValueException * If the file contains invalid syntax. */ public FileFormat loadConfigurationFile(String xmlFile) throws FlatwormUnsetFieldValueException, FlatwormConfigurationValueException { InputStream in = null; try { in = this.getClass().getClassLoader().getResourceAsStream(xmlFile); if (in == null) { in = (new FileInputStream(xmlFile)); } return loadConfigurationFile(in); } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { } } } return null; } public FileFormat loadConfigurationFile(InputStream in) throws FlatwormUnsetFieldValueException, FlatwormConfigurationValueException { DocumentBuilder parser; Document document; NodeList children; try { DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); parser = fact.newDocumentBuilder(); document = parser.parse((new org.xml.sax.InputSource(in))); children = document.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (("file-format".equals(child.getNodeName())) && (child.getNodeType() == Node.ELEMENT_NODE)) { return (FileFormat) traverse(child); } } } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } return null; } private List<Object> getChildNodes(Node node) throws FlatwormUnsetFieldValueException, FlatwormConfigurationValueException { List<Object> nodes = new ArrayList<Object>(); NodeList children = node.getChildNodes(); if (children != null) { for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); Object o = traverse(child); if (o != null) nodes.add(o); } } return nodes; } private boolean isElementNodeOfType(String type, Node node) { return type.equals(node.getNodeName()) && node.getNodeType() == 1; } private Node getChildElementNodeOfType(String type, Node node) { NodeList children = node.getChildNodes(); if (children != null) { for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (type.equals(child.getNodeName()) && child.getNodeType() == 1) return child; } } return null; } private List<Node> getChildElementNodesOfType(String type, Node node) { List<Node> nodes = new ArrayList<Node>(); NodeList children = node.getChildNodes(); if (children != null) { for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (type.equals(child.getNodeName()) && child.getNodeType() == 1) nodes.add(child); } } return nodes; } private String getChildTextNodeValue(Node node) { NodeList children = node.getChildNodes(); if (children != null) { for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeType() == 3) return child.getNodeValue(); } } return null; } private boolean hasAttributeValueNamed(Node node, String name) { return node.getAttributes().getNamedItem(name) != null; } private String getAttributeValueNamed(Node node, String name) { return hasAttributeValueNamed(node, name) ? node.getAttributes().getNamedItem(name).getNodeValue() : null; } private Node getAttributeNamed(Node node, String name) { NamedNodeMap map = node.getAttributes(); return map.getNamedItem(name); } private Object traverse(Node node) throws FlatwormUnsetFieldValueException, FlatwormConfigurationValueException { int type = node.getNodeType(); if (type == Node.ELEMENT_NODE) { String nodeName = node.getNodeName(); if (nodeName.equals("file-format")) { FileFormat f = new FileFormat(); String encoding = Charset.defaultCharset().name(); if (hasAttributeValueNamed(node, "encoding")) { encoding = getAttributeValueNamed(node, "encoding"); } f.setEncoding(encoding); List<Object> children = getChildNodes(node); for (int i = 0; i < children.size(); i++) { if (children.get(i).getClass().equals(Converter.class)) { f.addConverter((Converter) children.get(i)); } if (children.get(i).getClass().equals(Record.class)) { f.addRecord((Record) children.get(i)); } } return f; } if (nodeName.equals("converter")) { Converter c = new Converter(); c.setConverterClass(getAttributeValueNamed(node, "class")); c.setMethod(getAttributeValueNamed(node, "method")); c.setReturnType(getAttributeValueNamed(node, "return-type")); c.setName(getAttributeValueNamed(node, "name")); return c; } if (nodeName.equals("record")) { Record r = new Record(); r.setName(getAttributeValueNamed(node, "name")); Node identChild = getChildElementNodeOfType("record-ident", node); if (identChild != null) { Node fieldChild = getChildElementNodeOfType("field-ident", identChild); Node lengthChild = getChildElementNodeOfType("length-ident", identChild); if (lengthChild != null) { r.setLengthIdentMin(Integer.parseInt(getAttributeValueNamed(lengthChild, "minlength"))); r.setLengthIdentMax(Integer.parseInt(getAttributeValueNamed(lengthChild, "maxlength"))); r.setIdentTypeFlag('L'); } else if (fieldChild != null) { r.setFieldIdentStart(Integer.parseInt(getAttributeValueNamed(fieldChild, "field-start"))); r.setFieldIdentLength(Integer.parseInt(getAttributeValueNamed(fieldChild, "field-length"))); List<Node> matchNodes = getChildElementNodesOfType("match-string", fieldChild); for (int j = 0; j < matchNodes.size(); j++) { r.addFieldIdentMatchString(getChildTextNodeValue(matchNodes.get(j))); } r.setIdentTypeFlag('F'); } } Node recordChild = getChildElementNodeOfType("record-definition", node); r.setRecordDefinition((RecordDefinition) traverse(recordChild)); return r; } if (nodeName.equals("record-definition")) { RecordDefinition rd = new RecordDefinition(); List<Object> children = getChildNodes(node); for (int i = 0; i < children.size(); i++) { Object o = children.get(i); if (o.getClass().equals(Bean.class)) { rd.addBeanUsed((Bean) o); } if (o.getClass().equals(Line.class)) { rd.addLine((Line) o); } } return rd; } if (nodeName.equals("bean")) { Bean b = new Bean(); b.setBeanName(getAttributeValueNamed(node, "name")); b.setBeanClass(getAttributeValueNamed(node, "class")); try { b.setBeanObjectClass(Class.forName(b.getBeanClass())); } catch (ClassNotFoundException e) { throw new FlatwormConfigurationValueException("Unable to load class " + b.getBeanClass()); } return b; } if (nodeName.equals("line")) { Line li = new Line(); // JBL - Determine if this line is delimited // Determine value of quote character, default = " // These field is optional Node delimit = getAttributeNamed(node, "delimit"); Node quote = getAttributeNamed(node, "quote"); if (delimit != null) { li.setDelimeter(getAttributeValueNamed(node, "delimit")); } if (quote != null) { li.setQuoteChar(getAttributeValueNamed(node, "quote")); } List<Object> v = getChildNodes(node); for (int i = 0; i < v.size(); i++) { Object o = v.get(i); if (o instanceof LineElement) { li.addElement((LineElement) o); } } return li; } if (nodeName.equals("segment-element")) { SegmentElement segment = new SegmentElement(); segment.setCardinalityMode(CardinalityMode.LOOSE); segment.setName(getAttributeValueNamed(node, "name")); segment.setMinCount(Integer.parseInt(getAttributeValueNamed(node, "minCount"))); segment.setMaxCount(Integer.parseInt(getAttributeValueNamed(node, "maxCount"))); segment.setBeanRef(getAttributeValueNamed(node, "beanref")); segment.setParentBeanRef(getAttributeValueNamed(node, "parent-beanref")); segment.setAddMethod(getAttributeValueNamed(node, "addMethod")); String segmentMode = getAttributeValueNamed(node, "cardinality-mode"); if (!StringUtils.isBlank(segmentMode)) { if (segmentMode.toLowerCase().startsWith("strict")) { segment.setCardinalityMode(CardinalityMode.STRICT); } else if (segmentMode.toLowerCase().startsWith("restrict")) { segment.setCardinalityMode(CardinalityMode.RESTRICTED); } } Node fieldChild = getChildElementNodeOfType("field-ident", node); if (fieldChild != null) { segment.setFieldIdentStart(Integer.parseInt(getAttributeValueNamed(fieldChild, "field-start"))); segment.setFieldIdentLength( Integer.parseInt(getAttributeValueNamed(fieldChild, "field-length"))); List<Node> matchNodes = getChildElementNodesOfType("match-string", fieldChild); for (int j = 0; j < matchNodes.size(); j++) { segment.addFieldIdentMatchString(getChildTextNodeValue((Node) matchNodes.get(j))); } } validateSegmentConfiguration(segment); List<Object> v = getChildNodes(node); for (int i = 0; i < v.size(); i++) { Object o = v.get(i); if (o instanceof LineElement) { segment.addElement((LineElement) o); } } return segment; } if (nodeName.equals("record-element")) { RecordElement re = new RecordElement(); Node start = getAttributeNamed(node, "start"); Node end = getAttributeNamed(node, "end"); Node length = getAttributeNamed(node, "length"); Node beanref = getAttributeNamed(node, "beanref"); Node beanType = getAttributeNamed(node, "type"); if ((end == null) && (length == null)) { FlatwormConfigurationValueException err = new FlatwormConfigurationValueException( "Must set either the 'end' or 'length' properties"); throw err; } if ((end != null) && (length != null)) { FlatwormConfigurationValueException err = new FlatwormConfigurationValueException( "Can't specify both the 'end' or 'length' properties"); throw err; } if (start != null) { re.setFieldStart(Integer.parseInt(start.getNodeValue())); } if (end != null) { re.setFieldEnd(Integer.parseInt(end.getNodeValue())); } if (length != null) { re.setFieldLength(Integer.parseInt(length.getNodeValue())); } if (beanref != null) { re.setBeanRef(beanref.getNodeValue()); } if (beanType != null) { re.setType(beanType.getNodeValue()); } List<Node> children = getChildElementNodesOfType("conversion-option", node); for (int i = 0; i < children.size(); i++) { Node o = (Node) children.get(i); String name = getAttributeValueNamed(o, "name"); String value = getAttributeValueNamed(o, "value"); ConversionOption co = new ConversionOption(name, value); re.addConversionOption(name, co); } return re; } } return null; } private void validateSegmentConfiguration(SegmentElement segment) throws FlatwormConfigurationValueException { StringBuilder errors = new StringBuilder(); if (StringUtils.isBlank(segment.getBeanRef())) { if (!StringUtils.isBlank(segment.getName())) { segment.setBeanRef(segment.getName()); } else { errors.append("Must specify the beanref to be used, or a segment name that matches a bean name.\n"); } } if (StringUtils.isBlank(segment.getParentBeanRef())) { errors.append("Must specify the beanref for the parent onject."); } if (StringUtils.isBlank(segment.getAddMethod())) { if (errors.length() == 0) { segment.setAddMethod("add" + StringUtils.capitalize( StringUtils.isBlank(segment.getName()) ? segment.getBeanRef() : segment.getName())); } } if (segment.getFieldIdentMatchStrings().size() == 0) { errors.append("Must specify the segment identifier.\n"); } if (errors.length() > 0) { throw new FlatwormConfigurationValueException(errors.toString()); } } }