org.structr.websocket.command.LayoutsCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.structr.websocket.command.LayoutsCommand.java

Source

/**
 * Copyright (C) 2010-2016 Structr GmbH
 *
 * This file is part of Structr <http://structr.org>.
 *
 * Structr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Structr 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Structr.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.structr.websocket.command;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.structr.common.SecurityContext;
import org.structr.websocket.message.WebSocketMessage;
import org.structr.websocket.StructrWebSocket;
import org.structr.websocket.message.MessageBuilder;

//~--- JDK imports ------------------------------------------------------------

import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.structr.common.error.FrameworkException;
import org.structr.core.GraphObject;
import org.structr.core.GraphObjectMap;
import org.structr.core.app.App;
import org.structr.core.app.StructrApp;
import org.structr.core.graph.Tx;
import org.structr.core.property.GenericProperty;
import org.structr.core.property.Property;
import org.structr.rest.maintenance.SnapshotCommand;

//~--- classes ----------------------------------------------------------------

/**
 *
 *
 */
public class LayoutsCommand extends AbstractCommand {

    private static final Logger logger = Logger.getLogger(LayoutsCommand.class.getName());
    private static final Property<List<String>> layoutsProperty = new GenericProperty<>("layouts");

    static {

        StructrWebSocket.addCommand(LayoutsCommand.class);
    }

    @Override
    public void processMessage(final WebSocketMessage webSocketData) {

        final Map<String, Object> data = webSocketData.getNodeData();
        final String mode = (String) data.get("mode");
        final String name = (String) data.get("name");

        if (mode != null) {

            final List<GraphObject> result = new LinkedList<>();

            switch (mode) {

            case "list":

                final List<String> layouts = LayoutsCommand.listLayouts();

                if (layouts != null) {

                    final GraphObjectMap layoutContainer = new GraphObjectMap();

                    layoutContainer.put(layoutsProperty, layouts);
                    result.add(layoutContainer);

                    webSocketData.setResult(result);
                    webSocketData.setRawResultCount(1);
                    getWebSocket().send(webSocketData, true);
                }

                break;

            case "get":

                try {

                    final String content = new String(Files.readAllBytes(locateFile(name, false).toPath()));

                    getWebSocket().send(
                            MessageBuilder.finished().callback(callback).data("schemaLayout", content).build(),
                            true);

                } catch (IOException | FrameworkException ex) {

                    Logger.getLogger(LayoutsCommand.class.getName()).log(Level.SEVERE, null, ex);

                }

                break;

            case "add":

                final String positions = (String) data.get("schemaLayout");

                try {

                    final File layoutFile = locateFile(name, false);

                    if (layoutFile.exists()) {

                        getWebSocket().send(
                                MessageBuilder.status().code(422).message("Layout already exists!").build(), true);

                    } else {

                        createLayout(name, positions);

                    }

                    getWebSocket().send(MessageBuilder.finished().callback(callback).build(), true);

                } catch (FrameworkException ex) {

                    Logger.getLogger(LayoutsCommand.class.getName()).log(Level.SEVERE, null, ex);

                }

                break;

            case "delete":

                try {

                    deleteLayout(name);

                    getWebSocket().send(MessageBuilder.finished().callback(callback).build(), true);

                } catch (FrameworkException ex) {

                    Logger.getLogger(LayoutsCommand.class.getName()).log(Level.SEVERE, null, ex);

                }

                break;

            default:

                getWebSocket().send(MessageBuilder.status().code(422)
                        .message("Mode must be one of list, get, add or delete.").build(), true);

            }

        } else {

            getWebSocket().send(MessageBuilder.status().code(422)
                    .message("Mode must be one of list, get, add or delete.").build(), true);
        }
    }

    @Override
    public String getCommand() {

        return "LAYOUTS";

    }

    // ----- private methods -----
    private void createLayout(final String name, final String positions) throws FrameworkException {

        // we want to create a sorted, human-readble, diffable representation of the schema
        final App app = StructrApp.getInstance();

        // isolate write output
        try (final Tx tx = app.tx()) {

            final File layoutFile = locateFile(name, false);

            try (final Writer writer = new FileWriter(layoutFile)) {

                writer.append(positions);
                writer.append("\n"); // useful newline

                writer.flush();
            }

            tx.success();

        } catch (IOException ioex) {
            logger.log(Level.WARNING, "", ioex);
        }
    }

    private void deleteLayout(final String fileName) throws FrameworkException {

        if (fileName != null) {

            final File layoutFile = locateFile(fileName, false);
            layoutFile.delete();

        } else {

            throw new FrameworkException(422, "Please supply schema name to import.");
        }
    }

    public static List<String> listLayouts() {

        final File baseDir = new File(getBasePath());
        final List<String> fileNames = new LinkedList<>();

        if (baseDir.exists()) {

            final String[] names = baseDir.list();
            if (names != null) {

                fileNames.addAll(Arrays.asList(names));
            }
        }

        Collections.sort(fileNames, String.CASE_INSENSITIVE_ORDER);

        return fileNames;
    }

    public static File locateFile(final String name, final boolean addTimestamp) throws FrameworkException {

        String fileName = name;
        if (StringUtils.isBlank(fileName)) {

            // create default value
            fileName = "schema.json";
        }

        if (fileName.contains(System.getProperty("dir.separator", "/"))) {
            throw new FrameworkException(422,
                    "Only relative file names are allowed, please use the snapshot.path configuration setting to supply a custom path for snapshots.");
        }

        if (addTimestamp) {
            final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-HHmmss");
            fileName = format.format(System.currentTimeMillis()) + "-" + fileName;
        }

        // append JSON extension
        if (!fileName.endsWith(".json")) {
            fileName = fileName + ".json";
        }

        // create
        final File path = new File(getBasePath() + fileName);
        final File parent = path.getParentFile();
        if (!parent.exists()) {

            parent.mkdirs();
        }

        return path;
    }

    public static String getBasePath() {

        return "layouts/";
    }
}