001    /*
002     * CSVMappingParser.java
003     * 
004     * Copyright (C) 2005 Anupam Sengupta (anupamsg@users.sourceforge.net) 
005     * 
006     * This program is free software; you can redistribute it and/or 
007     * modify it under the terms of the GNU General Public License 
008     * as published by the Free Software Foundation; either version 2 
009     * of the License, or (at your option) any later version. 
010     * 
011     * This program is distributed in the hope that it will be useful, 
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of 
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
014     * GNU General Public License for more details. 
015     * 
016     * You should have received a copy of the GNU General Public License
017     * along with this program; if not, write to the Free Software 
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 
019     *
020     * Version: $Revision: 1.2 $
021     */
022    package net.sf.anupam.csv.mapping;
023    
024    import org.apache.commons.digester.Digester;
025    import org.apache.commons.digester.xmlrules.FromXmlRuleSet;
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogFactory;
028    import org.xml.sax.InputSource;
029    import org.xml.sax.SAXException;
030    
031    import java.io.BufferedInputStream;
032    import java.io.FileInputStream;
033    import java.io.FileNotFoundException;
034    import java.io.IOException;
035    import java.io.InputStream;
036    import java.util.ArrayList;
037    import java.util.List;
038    import java.util.Map;
039    import java.util.WeakHashMap;
040    
041    /**
042     * XML Parser (based on Commons Digester) to parse and return the mapping
043     * configuration.
044     *
045     * @author Anupam Sengupta
046     * @version $Revision: 1.2 $
047     * @see org.apache.commons.digester.Digester
048     * @since 1.5
049     */
050    public class CSVMappingParser {
051    
052        /**
053         * The logger to use.
054         */
055        private static final Log LOG = LogFactory
056                .getLog(CSVMappingParser.class);
057    
058        /**
059         * The digester rule set for parsing the mapping file.
060         */
061        private static FromXmlRuleSet ruleSet;
062    
063        /**
064         * The digester to use for parsing the mapping file.
065         */
066        private Digester digester = new Digester();
067    
068        static {
069    
070            final InputStream is = ClassLoader
071                    .getSystemResourceAsStream("net/sf/anupam/csv/mapping/csv-mapping-digester-rules.xml");
072            if (is != null) {
073                final InputSource isrc = new InputSource(is);
074                ruleSet = new FromXmlRuleSet(isrc);
075                LOG.info("Loaded Digester Rules for "
076                        + CSVMappingParser.class);
077            } else {
078                LOG.error("The CSV Mapping Digester Rules XML was not found");
079            }
080    
081        }
082    
083        /**
084         * Constructor for CSVMappingParser.
085         */
086        public CSVMappingParser() {
087            super();
088            digester.clear();
089    
090            CSVMappingParser.ruleSet.addRuleInstances(digester);
091            digester.push(new ArrayList<CSVBeanMapping>());
092    
093        }
094    
095        /**
096         * Finalizes this mapping parser.
097         *
098         * @throws Throwable thrown if the finalization fails
099         * @see Object#finalize()
100         */
101        @Override
102        protected void finalize() throws Throwable {
103            super.finalize();
104            if (digester != null) {
105                digester.clear();
106                digester = null;
107            }
108        }
109    
110        /**
111         * Returns the map of parsed mapping configuration beans.
112         *
113         * @param xmlFileName the XML mapping configuration file
114         * @param inClassPath flag indicating whether the XML file is in the classpath
115         * @return a map of CSV bean mappings. An empty map is returned if an error
116         *         occurs
117         */
118        public Map<String, CSVBeanMapping> getMappings(final String xmlFileName,
119                                                       final boolean inClassPath) {
120    
121            final Map<String, CSVBeanMapping> beanMap = new WeakHashMap<String, CSVBeanMapping>();
122    
123            try {
124                final InputStream xmlStream = (inClassPath)
125                        ? ClassLoader.getSystemResourceAsStream(xmlFileName)
126                        : new BufferedInputStream(new FileInputStream(xmlFileName));
127    
128                final InputSource inputSrc = new InputSource(xmlStream);
129    
130                final List<CSVBeanMapping> mappingList = (List<CSVBeanMapping>) digester
131                        .parse(inputSrc);
132    
133                for (CSVBeanMapping mappedBean : mappingList) {
134                    beanMap.put(mappedBean.getBeanName(), mappedBean);
135                }
136            } catch (final FileNotFoundException e) {
137                LOG.warn("The XML File: "
138                        + xmlFileName + " was not found", e);
139            } catch (final IOException e) {
140                LOG.warn("The XML File: "
141                        + xmlFileName + " could not be read", e);
142            } catch (final SAXException e) {
143                LOG.warn("The XML File: "
144                        + xmlFileName + " could not be parsed", e);
145            }
146            return beanMap;
147        }
148    
149    }