/* * Copyright (c) 2012. HappyDroids LLC, All rights reserved. */ package sk.seges.acris.json.server.migrate; import com.badlogic.gdx.Gdx; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import javax.script.ScriptException; import java.io.*; /** * Transforms JSON data using Jackson's tree model based scripts. * * @author ladislav.gazo * @see sk.seges.acris.json.server.migrate.JacksonTransformationScript */ public class JacksonTransformer extends Transformer<String> { private static final String TAG = JacksonTransformer.class.getSimpleName(); private static final int EOF = -1; private final String fileName; public JacksonTransformer(InputStream inputStream, String fileName) throws ScriptException, FileNotFoundException { super(inputStream); this.fileName = fileName; } @SuppressWarnings("unchecked") @Override public byte[] transform(Class<? extends JacksonTransformationScript> transformationClass, ByteArrayInputStream input) { ObjectMapper mapper = new ObjectMapper(); try { JsonNode jsonNode = mapper.readValue(input, JsonNode.class); Gdx.app.debug(TAG, "Executing migration: " + transformationClass.getSimpleName()); JacksonTransformationScript transformation = transformationClass.newInstance(); transformation.process(jsonNode, fileName); return mapper.writeValueAsBytes(jsonNode); } catch (Exception e) { throw new RuntimeException("Unable to transform data using transformationClass = " + transformationClass, e); } } @Override public byte[] process() throws IOException { byte bytes[] = new byte[inputStream.available()]; readFully(inputStream, bytes); ByteArrayOutputStream output = new ByteArrayOutputStream(); for (Class<? extends JacksonTransformationScript> transformClass : transforms) { ByteArrayInputStream input = new ByteArrayInputStream(bytes); bytes = transform(transformClass, input); } return bytes; } private void readFully(InputStream inputStream, byte[] bytes) throws IOException { int length = bytes.length; int remaining = length; while (remaining > 0) { int location = length - remaining; int count = inputStream.read(bytes, location, remaining); if (EOF == count) { // EOF break; } remaining -= count; } } }