/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2010-2015, Geomatys * * 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. */ package org.geotoolkit.report; import java.io.Closeable; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRField; import org.apache.sis.util.ObjectConverters; import org.apache.sis.util.UnconvertibleObjectException; import org.apache.sis.util.logging.Logging; import static org.apache.sis.util.ArgumentChecks.*; import org.geotoolkit.filter.binding.Bindings; import org.opengis.feature.Feature; import org.opengis.feature.Property; import org.opengis.feature.PropertyNotFoundException; /** * Map a Collection as a Jasper report data source. * * @author Johann Sorel (Geomatys) */ public class CollectionDataSource implements JRDataSource { private final Collection col; private final Iterator iterator; private Object candidate; public CollectionDataSource(final Collection collection){ ensureNonNull("collection", collection); this.col = collection; this.iterator = collection.iterator(); } public CollectionDataSource(final Iterator iterator){ ensureNonNull("iterator", iterator); this.col = null; this.iterator = iterator; } public CollectionDataSource cloneDataSource(){ if(col!=null){ return new CollectionDataSource(col); } else { throw new UnsupportedOperationException("This operation needs the data source has a feature collection."); } } @Override public boolean next() throws JRException { if(iterator.hasNext()){ candidate = iterator.next(); return true; }else{ if(col != null && iterator instanceof Closeable){ try { //we created the iterator, we close it ((Closeable)iterator).close(); } catch (IOException ex) { throw new JRException(ex.getMessage(), ex); } } return false; } } @Override public Object getFieldValue(final JRField jrf) throws JRException { //search for special fields if(candidate instanceof Feature){ final Collection<JRFieldRenderer> renderers = JasperReportService.getFieldRenderers(); for(JRFieldRenderer r : renderers){ if(r.canHandle(jrf)){ return r.createValue(jrf,(Feature)candidate); } } } //casual field types final String name = jrf.getName(); if(candidate instanceof Feature){ try{ final Property prop = ((Feature)candidate).getProperty(name); if(prop != null){ //just in case the type is not rigourously the same. final Class clazz = jrf.getValueClass(); try { return ObjectConverters.convert(prop.getValue(), clazz); } catch (UnconvertibleObjectException e) { Logging.recoverableException(null, CollectionDataSource.class, "getFieldValue", e); // TODO - do we really want to ignore? } } }catch(PropertyNotFoundException ex){ return null; } //No field that match this name, looks like the feature type //used is not the exact one returned by the JasperReportservice. //This is not necessarly an error if for exemple someone ignore //some attribut from the template because he doesn't need them. return null; }else{ return Bindings.resolve(candidate, name, jrf.getValueClass()); } } }