package org.geotoolkit.wps.converters.outputs.complex; import net.iharder.Base64; import org.geotoolkit.nio.IOUtilities; import org.apache.sis.util.UnconvertibleObjectException; import org.geotoolkit.wps.io.WPSEncoding; import org.geotoolkit.wps.io.WPSMimeType; import org.geotoolkit.wps.xml.ComplexDataType; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; import static org.geotoolkit.wps.converters.WPSObjectConverter.ENCODING; import static org.geotoolkit.wps.converters.WPSObjectConverter.MIME; import org.geotoolkit.wps.xml.WPSXmlFactory; /** * A converter to transform a File into ComplexOutput data for wps ExecuteResponse query. * * @author Alexis Manin (Geomatys) */ public class FileToComplexConverter extends AbstractComplexOutputConverter<File> { private static FileToComplexConverter INSTANCE; private FileToComplexConverter() { } public static synchronized FileToComplexConverter getInstance() { if (INSTANCE == null) { INSTANCE = new FileToComplexConverter(); } return INSTANCE; } @Override public Class<File> getSourceClass() { return File.class; } /** * Convert a file into ComplexDataType object, according to the specifications given in params parameter. * * @param source The file to convert. * @param params The parameters used for conversion (Mime-Type/encoding). If null, mime is set to application/octet-stream, and encoding to base64 * @return * @throws UnconvertibleObjectException */ @Override public ComplexDataType convert(File source, Map<String, Object> params) throws UnconvertibleObjectException { if (source == null) { throw new UnconvertibleObjectException("The output data should be defined."); } if (params == null) { throw new UnconvertibleObjectException("Mandatory parameters are missing."); } String wpsVersion = (String) params.get(WPSVERSION); if (wpsVersion == null) { LOGGER.warning("No WPS version set using default 1.0.0"); wpsVersion = "1.0.0"; } String mime = (String) params.get(MIME); String encoding = (String) params.get(ENCODING); if (mime == null) { mime = WPSMimeType.APP_OCTET.val(); encoding = WPSEncoding.BASE64.getValue(); } final ComplexDataType complex = WPSXmlFactory.buildComplexDataType(wpsVersion, mime,encoding, null); //Plain text if (mime.startsWith("text")) { //XML is special case, we try to find an associate schema. if (mime.contains("xml") || mime.contains("gml")) { String schemaLocation = source.getAbsolutePath(); schemaLocation.replace("\\.[a-z]ml", "").concat(".xsd"); File ogrSchema = new File(schemaLocation); // If we find a schema, we ensure it's location is public before giving it. if (ogrSchema.exists()) { String tmpDir = (String) params.get(TMP_DIR_PATH); String tmpURL = (String) params.get(TMP_DIR_URL); if (tmpDir == null || tmpURL == null) { throw new UnconvertibleObjectException("Mandatory parameters are missing."); } if (!schemaLocation.contains(tmpDir)) { String schemaName = source.getName().replace("\\.[a-z]ml", "").concat(".xsd"); Path schemaDest = Paths.get(tmpDir, schemaName); try { IOUtilities.copy(source.toPath(), schemaDest); schemaLocation = schemaDest.toAbsolutePath().toString(); } catch (IOException e) { throw new UnconvertibleObjectException("Unexpected error on schema copy.", e); } } complex.setSchema(schemaLocation.replace(tmpDir, tmpURL)); } } // CData needed because files could contain problematic characters. complex.getContent().add("<![CDATA["); complex.getContent().add(source); complex.getContent().add("]]>"); } else { //If no text format, We'll put it as a base64 object. if (encoding == null || !encoding.equals(WPSEncoding.BASE64.getValue())) { throw new UnconvertibleObjectException("Encoding should be in Base64 for complex request."); } try (FileInputStream stream =new FileInputStream(source)) { byte[] barray = new byte[(int) source.length()]; stream.read(barray); complex.getContent().add(Base64.encodeBytes(barray)); } catch (Exception ex) { throw new UnconvertibleObjectException(ex.getMessage(), ex); } } return complex; } }