/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * (C) 2011, 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 3 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.wps.converters.inputs.references; import java.awt.geom.AffineTransform; import java.io.InputStream; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import org.geotoolkit.mathml.xml.Mtable; import org.geotoolkit.mathml.xml.Mtr; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.UnconvertibleObjectException; import org.geotoolkit.wps.converters.WPSConvertersUtils; import org.geotoolkit.wps.io.WPSMimeType; import org.geotoolkit.wps.xml.Reference; import org.geotoolkit.wps.xml.WPSMarshallerPool; /** * * @author Quentin Boileau (Geomatys). */ public class ReferenceToAffineTransformConverter extends AbstractReferenceInputConverter<AffineTransform> { private static ReferenceToAffineTransformConverter INSTANCE; private ReferenceToAffineTransformConverter() { } public static synchronized ReferenceToAffineTransformConverter getInstance() { if (INSTANCE == null) { INSTANCE = new ReferenceToAffineTransformConverter(); } return INSTANCE; } @Override public Class<AffineTransform> getTargetClass() { return AffineTransform.class; } @Override public AffineTransform convert(final Reference source, final Map<String, Object> params) throws UnconvertibleObjectException { final String mime = source.getMimeType() != null ? source.getMimeType() : WPSMimeType.TEXT_XML.val(); final InputStream stream = getInputStreamFromReference(source); if (mime.equalsIgnoreCase(WPSMimeType.TEXT_XML.val()) || mime.equalsIgnoreCase(WPSMimeType.APP_GML.val()) || mime.equalsIgnoreCase(WPSMimeType.TEXT_GML.val())) { try { final Unmarshaller unmarsh = WPSMarshallerPool.getInstance().acquireUnmarshaller(); Object value = unmarsh.unmarshal(stream); WPSMarshallerPool.getInstance().recycle(unmarsh); return bindToAffineTransform(value); } catch (JAXBException ex) { throw new UnconvertibleObjectException("Reference geometry invalid input : Unmarshallable geometry", ex); } } else { throw new UnconvertibleObjectException("Reference data mime is not supported"); } } private AffineTransform bindToAffineTransform(final Object object) throws UnconvertibleObjectException { ArgumentChecks.ensureNonNull("object", object); AffineTransform affineTransform = null; if (object instanceof org.geotoolkit.mathml.xml.Math) { final org.geotoolkit.mathml.xml.Math math = (org.geotoolkit.mathml.xml.Math) object; final List<Object> mathExp = math.getMathExpression(); if (mathExp != null && !mathExp.isEmpty()) { final Mtable mtable = WPSConvertersUtils.findMtable(mathExp); if (mtable == null) { throw new UnconvertibleObjectException("No mtable element found."); } final List<Mtr> rows = WPSConvertersUtils.getRows(mtable); final int nbRows = rows.size(); final int nbCells = WPSConvertersUtils.getCells(rows.get(0)).length; if (nbRows != 2 || (nbCells != 2 && nbCells != 3)) { throw new UnconvertibleObjectException("The matrix need to be a 2x2 or a 3x3 matrix ."); } final double[][] matrix = new double[nbRows][nbCells]; for (int i = 0; i < nbRows; i++) { final double[] cells = WPSConvertersUtils.getCells(rows.get(i)); if (cells.length != nbCells) { throw new UnconvertibleObjectException("The matrix need to be a 2x2 or a 3x3 matrix ."); } System.arraycopy(cells, 0, matrix[i], 0, nbCells); } //TODO optimize double[] flatMatrix = new double[nbCells*nbRows]; int count = 0; for (int i = 0; i < nbCells; i++) { for (int j = 0; j < nbRows; j++) { flatMatrix[count++] = matrix[j][i]; } } affineTransform = new AffineTransform(flatMatrix); } } return affineTransform; } }