/* * Copyright 2005 JBoss Inc * * 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 org.drools.decisiontable.parser.xls; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.drools.template.parser.DataListener; /** * Reads an Excel sheet as key-value properties. * * Treats the first non-empty cell on a row as a key and any subsequent * non-empty cell as a value. Any cells defined after the second cell are * ignored as comments. * * Could be easily adapted to accept multiple values per key but the semantics * were kept in line with Properties. * * @author <a href="mailto:shaun.addison@gmail.com"> Shaun Addison </a> * */ public class PropertiesSheetListener implements DataListener { private static final String EMPTY_STRING = ""; private final Map<Integer, String[]> _rowProperties = new HashMap<Integer, String[]>(); private final Properties _properties = new CaseInsensitiveMap(); /** * Return the key value pairs. If this is called before the sheet is * finished, then it will build the properties map with what is known. * Subsequent calls will update the properties map. * * @return properties */ public Properties getProperties() { finishSheet(); // MN allows this to be called before the sheet is // finished, as // some properties are used whilst the sheet is being parsed. return this._properties; } /* * (non-Javadoc) * * @see my.hssf.util.SheetListener#startSheet(java.lang.String) */ public void startSheet(final String name) { } /* * (non-Javadoc) * * @see my.hssf.util.SheetListener#finishSheet() */ public void finishSheet() { for ( String[] keyValue : _rowProperties.values() ) { this._properties.put( keyValue[0], keyValue[1] ); } } /** * Enter a new row. This is ignored. * * @param rowNumber * The row number. * @param columns * The Colum number. */ public void newRow(final int rowNumber, final int columns) { // nothing to do. } /* * (non-Javadoc) * * @see my.hssf.util.SheetListener#newCell(int, int, java.lang.String) */ public void newCell(final int row, final int column, final String value, final int mergedColStart) { if ( emptyCellValue( value ) ) { return; } final Integer rowInt = new Integer( row ); if ( this._rowProperties.containsKey( rowInt ) ) { final String[] keyValue = (String[]) this._rowProperties.get( rowInt ); if ( keyValue[1] == PropertiesSheetListener.EMPTY_STRING ) { keyValue[1] = value; } } else { final String[] keyValue = {value, PropertiesSheetListener.EMPTY_STRING}; this._rowProperties.put( rowInt, keyValue ); } } private boolean emptyCellValue(final String value) { return value == null || value.trim().equals( "" ); } @SuppressWarnings("serial") public static class CaseInsensitiveMap extends Properties { @Override public String getProperty(String key) { if (this.containsKey(key)) { return super.getProperty(key); } return get(key); } @Override public String getProperty(String key, String defaultValue) { String r = getProperty(key); return (r != null) ? r : defaultValue; } private String get(String key) { Enumeration< ? > keyNames = this.propertyNames(); while ( keyNames.hasMoreElements() ) { String k = (String) keyNames.nextElement(); if (key.equalsIgnoreCase( k )) { return super.getProperty( k ); } } return null; } } }