draw.chemy.JSONLoader.java Source code

Java tutorial

Introduction

Here is the source code for draw.chemy.JSONLoader.java

Source

/*
 * This file is part of the Drawchemy project - https://github.com/PPilmeyer/drawchemy
 *
 * Copyright (c) 2015 Pilmeyer Patrick
 *
 * Drawchemy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Drawchemy 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Drawchemy.  If not, see <http://www.gnu.org/licenses/>.
 */

package draw.chemy;

import android.content.Context;
import android.graphics.Path;
import android.graphics.PointF;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import static draw.chemy.creator.ComplexShapeCreator.Shape;
import static draw.chemy.creator.ComplexShapeCreator.ShapeGroup;

public class JSONLoader {

    private final Map<String, SVGPathCommand> fSVGCommands = new HashMap<String, SVGPathCommand>();

    private static JSONLoader sInstance;

    private JSONLoader() {
        SVGPathCommand op = new RelativeMove();
        fSVGCommands.put(op.getKey(), op);
        op = new Close();
        fSVGCommands.put(op.getKey(), op);
        op = new RelLineTo();
        fSVGCommands.put(op.getKey(), op);
        op = new RelBezier();
        fSVGCommands.put(op.getKey(), op);
        op = new Move();
        fSVGCommands.put(op.getKey(), op);
        op = new LineTo();
        fSVGCommands.put(op.getKey(), op);
        op = new Bezier();
        fSVGCommands.put(op.getKey(), op);
    }

    public static JSONLoader getInstance() {
        if (sInstance == null) {
            sInstance = new JSONLoader();
        }
        return sInstance;
    }

    public ShapeGroup loadJSON(Context aContext, int aID) throws JSONException, IOException {
        InputStream in = aContext.getResources().openRawResource(aID);
        ByteArrayOutputStream byteArrayOutputStream;

        int ctr = in.read();
        byteArrayOutputStream = new ByteArrayOutputStream();
        while (ctr != -1) {
            byteArrayOutputStream.write(ctr);
            ctr = in.read();
        }
        in.close();
        JSONObject jObject = new JSONObject(byteArrayOutputStream.toString());
        Iterator<String> keys = jObject.keys();
        ShapeGroup result = new ShapeGroup();
        while (keys.hasNext()) {

            String next = keys.next();
            List<Path> pathList = createPath(jObject.getString(next));
            result.addShape(new Shape(pathList));
        }
        return result;
    }

    private List<Path> createPath(String aPath) {
        StringTokenizer tokenizer = new StringTokenizer(aPath);
        List<Path> result = new ArrayList<Path>();
        List<PointF> tempPointFs = new ArrayList<PointF>();
        SVGPathCommand currentOp = null;
        PointF lastPointF = new PointF(0f, 0f);
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (token.contains(",")) {
                String[] split = token.split(",");
                PointF PointF = new PointF(Float.parseFloat(split[0]), Float.parseFloat(split[1]));
                tempPointFs.add(PointF);
            } else if (fSVGCommands.containsKey(token)) {
                if (currentOp != null) {
                    currentOp.operation(tempPointFs, result, lastPointF);
                }
                currentOp = fSVGCommands.get(token);
                tempPointFs.clear();
            }
        }
        if (currentOp != null) {
            currentOp.operation(tempPointFs, result, lastPointF);
        }
        return result;
    }

    abstract class SVGPathCommand {

        private final String fKey;

        protected SVGPathCommand(String aKey) {
            fKey = aKey;
        }

        public final String getKey() {
            return fKey;
        }

        public abstract void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT);
    }

    private class RelativeMove extends SVGPathCommand {
        protected RelativeMove() {
            super("m");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            aPathListSFCT.add(new Path());
            Path path = aPathListSFCT.get(aPathListSFCT.size() - 1);
            PointF p = aPointFList.get(0);
            float x = p.x + lastPointFSFCT.x;
            float y = p.y + lastPointFSFCT.y;
            lastPointFSFCT.set(x, y);
            path.moveTo(x, y);
        }
    }

    private class Move extends SVGPathCommand {
        protected Move() {
            super("M");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            Path path = new Path();
            aPathListSFCT.add(path);
            PointF p = aPointFList.get(0);
            lastPointFSFCT.set(p);
            path.moveTo(p.x, p.y);
        }
    }

    private class Close extends SVGPathCommand {
        protected Close() {
            super("z");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            aPathListSFCT.get(aPathListSFCT.size() - 1).close();
        }
    }

    private class RelLineTo extends SVGPathCommand {
        protected RelLineTo() {
            super("l");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            Path path = aPathListSFCT.get(aPathListSFCT.size() - 1);
            for (PointF PointF : aPointFList) {
                path.rLineTo(PointF.x, PointF.y);
            }
        }
    }

    private class LineTo extends SVGPathCommand {
        protected LineTo() {
            super("L");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            Path path = aPathListSFCT.get(aPathListSFCT.size() - 1);
            for (PointF PointF : aPointFList) {
                path.lineTo(PointF.x, PointF.y);
            }
        }
    }

    private class RelBezier extends SVGPathCommand {
        protected RelBezier() {
            super("c");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            Path path = aPathListSFCT.get(aPathListSFCT.size() - 1);
            for (int i = 0; i < aPointFList.size(); i += 3) {
                PointF p1 = aPointFList.get(i);
                PointF p2 = aPointFList.get(i + 1);
                PointF p3 = aPointFList.get(i + 2);
                path.rCubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
            }
        }
    }

    private class Bezier extends SVGPathCommand {
        protected Bezier() {
            super("C");
        }

        @Override
        public void operation(List<PointF> aPointFList, List<Path> aPathListSFCT, PointF lastPointFSFCT) {
            Path path = aPathListSFCT.get(aPathListSFCT.size() - 1);
            for (int i = 0; i < aPointFList.size(); i += 3) {
                PointF p1 = aPointFList.get(i);
                PointF p2 = aPointFList.get(i + 1);
                PointF p3 = aPointFList.get(i + 2);
                path.cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
            }
        }
    }
}