001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.dataAccess.file;
019
020import com.moandjiezana.toml.Toml;
021import com.moandjiezana.toml.TomlWriter;
022import io.stallion.dataAccess.MappedModel;
023import io.stallion.dataAccess.Model;
024import io.stallion.exceptions.ConfigException;
025import io.stallion.fileSystem.TreeVisitor;
026import io.stallion.reflection.PropertyUtils;
027import io.stallion.services.Log;
028import io.stallion.settings.Settings;
029import org.apache.commons.io.FileUtils;
030
031import java.io.File;
032import java.io.IOException;
033import java.nio.file.FileSystems;
034import java.nio.file.Files;
035import java.nio.file.Path;
036import java.util.*;
037
038import static io.stallion.utils.Literals.*;
039
040
041public class TomlPersister<T extends Model> extends FilePersisterBase<T> {
042
043    private static final Set<String> extensions = set("toml");
044    @Override
045    public Set<String> getFileExtensions() {
046        return extensions;
047    }
048
049    @Override
050    public List fetchAll()  {
051        File target = new File(Settings.instance().getTargetFolder());
052        if (!target.isDirectory()) {
053            if (getItemController().isWritable()) {
054                target.mkdirs();
055            } else {
056                throw new ConfigException(String.format("The TOML bucket %s (path %s) is read-only, but does not exist in the file system. Either create the folder, make it writable, or remove it from the configuration.", getItemController().getBucket(), getBucketFolderPath()));
057            }
058        }
059        TreeVisitor visitor = new TreeVisitor();
060        Path folderPath = FileSystems.getDefault().getPath(getBucketFolderPath());
061        try {
062            Files.walkFileTree(folderPath, visitor);
063        } catch (IOException e) {
064            throw new RuntimeException(e);
065        }
066        List<Object> objects = new ArrayList<>();
067        for (Path path : visitor.getPaths()) {
068            if (!path.toString().toLowerCase().endsWith(".toml")) {
069                continue;
070            }
071            if (path.toString().contains(".#")) {
072                continue;
073            }
074            Log.fine("Load from toml file " + path);
075            if (isManyItemsPerFile()) {
076                try {
077                    Log.finer("Load toml path {0} and items {1}", path.toString(), getItemArrayName());
078                    String toml = FileUtils.readFileToString(new File(path.toString()), UTF8);
079                    Toml t = new Toml().read(toml);
080                    List<HashMap> models = t.getList(getItemArrayName());
081                    long x = 0;
082                    for (Map m: models) {
083                        x++;
084                        T o = getModelClass().newInstance();
085                        for (Object key: m.keySet()) {
086                            PropertyUtils.setProperty(o, key.toString(), m.get(key));
087                        }
088                        Log.info("add item {0}", ((MappedModel)o).get("title"));
089                        if (empty(o.getId())) {
090                            o.setId(x);
091                        }
092                        handleFetchOne(o);
093                        objects.add(o);
094                    }
095                } catch (IOException e) {
096                    throw new RuntimeException(e);
097                } catch (IllegalAccessException e) {
098                    throw new RuntimeException(e);
099                } catch (InstantiationException e) {
100                    throw new RuntimeException(e);
101                }
102
103
104            } else {
105                objects.add(fetchOne(path.toString()));
106            }
107
108
109        }
110        return objects;
111    }
112
113    public String makePathForObject(T obj) {
114        return obj.getId() + ".toml";
115    }
116
117
118    public T doFetchOne(File file) {
119        T o = null;
120        try {
121            String toml = FileUtils.readFileToString(file, UTF8);
122            o = new Toml().read(toml).to(this.getModelClass());
123        } catch (IOException e) {
124            throw new RuntimeException(e);
125        }
126        return o;
127    }
128
129
130    @Override
131    public void persist(T obj) {
132        TomlWriter writer = new TomlWriter();
133
134        try {
135            writer.write(obj, new File(fullFilePathForObj(obj)));
136        } catch (IOException e) {
137            throw new RuntimeException(e);
138        }
139
140    }
141
142
143}
144
145