registry.ExtensionRegistryController.java Source code

Java tutorial

Introduction

Here is the source code for registry.ExtensionRegistryController.java

Source

/*
 * #%L
 * Wisdom-Framework
 * %%
 * Copyright (C) 2013 - 2014 Wisdom Framework
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package registry;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import javassist.util.proxy.Proxy;
import org.apache.commons.io.IOUtils;
import org.apache.felix.ipojo.annotations.Requires;
import org.wisdom.api.DefaultController;
import org.wisdom.api.annotations.*;
import org.wisdom.api.content.Json;
import org.wisdom.api.http.HttpMethod;
import org.wisdom.api.http.Result;
import org.wisdom.api.security.Authenticated;
import org.wisdom.api.templates.Template;
import org.wisdom.monitor.service.MonitorExtension;
import org.wisdom.orientdb.object.OrientDbCrud;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;

/**
 * A controller to manage the list of extensions available for the Wisdom framework.
 * The list is saved in memory using the Wisdom-OrientDB extension. Database is configured in the
 * application.conf file. Some methods have authorisation limited to Monitor authentication.
 */

@Controller

public class ExtensionRegistryController extends DefaultController implements MonitorExtension {

    @View("registry/managerView")
    Template manage;
    @View("registry/userView")
    Template user;
    @View("registry/developerView")
    Template dev;

    @Model(value = Extension.class)
    private OrientDbCrud<Extension, String> extensionCrud;

    Class klass = Proxy.class;

    @Requires
    Json json;

    /**
     * The action method returning the user's view of the extension page. It handles
     * HTTP GET request on the "/user" URL.
     *
     * @return the user extension page.
     */

    @Route(method = HttpMethod.GET, uri = "/registry")
    public Result user() {
        return ok(render(user));
    }

    /**
     * The action method returning the developer's view of the extension page. It handles
     * HTTP GET request on the "/dev" URL.
     * TODO: Separate authorisation
     * @return the developer extension page.
     */
    @Route(method = HttpMethod.GET, uri = "/registry/dev")
    public Result dev() {
        return ok(render(dev));
    }

    /**
     * The action method returning the administration's view of the extension page. It handles
     * HTTP GET request on the "/monitor/manage" URL.  It is accessed via the Wisdom Monitor.
     *
     * @return the managed extension page.
     */
    @Authenticated("Monitor-Authenticator")
    @Route(method = HttpMethod.GET, uri = "/monitor/registry/manage")
    public Result manage() {
        return ok(render(manage));
    }

    /**
     * The action method returning the user's view of the extension page. It handles
     * HTTP GET request on the "/list" URL.
     *
     * @return extension list in a json structure.
     */
    @Route(method = HttpMethod.GET, uri = "/registry/list")
    public Result get() {

        List<Extension> list = new LinkedList<Extension>();
        for (Extension extension : extensionCrud.findAll()) {
            list.add(extension);
        }
        return ok(list).json();
    }

    /**
     * The action method deleting a specific extension from the database. It handles
     * HTTP DELETE request on the "/list" URL.  Must be authenticated via the Wisdom Monitor
     * for this method.
     *
     * @return result.
     */
    @Authenticated("Monitor-Authenticator")
    @Route(method = HttpMethod.DELETE, uri = "/registry/list/{id}")
    public Result delete(@Parameter("id") String id) {
        removeExtensionById(id);
        return ok();
    }

    /**
     * The action method deleting a specific extension from the database. It handles
     * HTTP DELETE request on the "/list" URL.  Must be authenticated via the Wisdom Monitor
     * for this method.
     *
     * @return result.
     */
    @Authenticated("Monitor-Authenticator")
    @Route(method = HttpMethod.POST, uri = "/registry/list/{id}")
    public Result update(@Parameter("id") String id) {
        String url = extensionCrud.findOne(id).getSelf();
        return ok(parseUrl(url));
    }

    /**
     * The action method that loads a json object via a url and adds it to the database. It handles
     * HTTP POST request on the "/upload" URL.
     *
     * @return json structure containing the new extension
     */
    @Route(method = HttpMethod.POST, uri = "/registry/upload")
    public Result addExt(final @FormParameter("url") String u) {
        return ok(parseUrl(u));
    }

    /**
     * A method that parses a url expecting a json object.
     * @param url the url to be parsed.
     * @return  the json object if everything went well or a json object with an error msg if it
     * didn't.
     */
    private Result parseUrl(final String url) {
        return async(new Callable<Result>() {
            @Override
            public Result call() throws Exception {

                try {
                    URL u = new URL(url);
                    String j = IOUtils.toString(u);
                    JsonNode node = json.parse(j);
                    node = createExt((ObjectNode) node, url);
                    return ok(node);
                } catch (IOException e) {
                    // Cannot read the URL
                    logger().error("File not found or is unable to be read " + e);

                    return ok(json.newObject().put("error", "An error has occurred:").put("reason",
                            "File not found or unable to be read."));
                } catch (Exception e) {
                    logger().error(" A problem has occurred please check that your file is " + "valid JSON. "
                            + " - " + e.getMessage() + " (" + e.getClass().getName() + ")", e);
                    return ok(json.newObject().put("error", "An error has occurred:").put("reason",
                            "Please check that your file is " + "valid JSON. "));
                }
            }
        });
    }

    /**
     * Method that reads a json structure validating that it has all of the required javabean
     * fields that cannot be null by using Validator. If all goes well the object is added to the
     * database or updated if it already exists.
     *
     * @return json structure containing either the extension or error message
     */
    @Requires
    Validator validator;

    private JsonNode createExt(ObjectNode node, String url) {
        ObjectNode result = json.newObject();
        //map our incoming json to the
        Extension extension = json.mapper().convertValue(node, Extension.class);
        Set<ConstraintViolation<Extension>> errors = validator.validate(extension);
        if (!errors.isEmpty()) {
            Iterator<ConstraintViolation<Extension>> i = errors.iterator();
            String msg = "";
            while (i.hasNext()) {
                msg = msg + i.next().getPropertyPath() + " ";

            }
            result.put("error", "Error while adding extension").put("reason", msg + "need(s) to be set");
            logger().error("Something really bad happened...");
            logger().error(errors.toString());
            return result;
        }

        List<Extension> omg = extensionCrud.query(new OSQLSynchQuery<Extension>(
                "select * " + "from  " + "Extension where name like '" + extension.getName() + "'"));

        if (!omg.isEmpty()) {
            updateExtInDB(extension, url, omg.get(0));
            node.put("updated", true);
        } else {
            addExtToDB(extension, url);
            node.put("updated", false);
        }
        return node;
    }

    private void addExtToDB(Extension extension, String url) {
        extension.setDateAdded(new SimpleDateFormat("dd-MM-yyyy").format(new Date()));
        extension.setSelf(url);
        extensionCrud.save(extension);

    }

    private void updateExtInDB(Extension extension, String url, Extension oldExt) {
        extension.setDateAdded(oldExt.getDateAdded());
        extension.setDateUpdated(new SimpleDateFormat("dd-MM-yyyy").format(new Date()));
        extension.setSelf(url);
        removeExtensionById(oldExt.getId());
        extensionCrud.save(extension);

    }

    /**
     * Deletes the extension specified by database id from the database.
     * @param id is the id field in the database for the extension.
     */
    private void removeExtensionById(String id) {
        extensionCrud.delete(id);
    }

    /**
     * Method required from implementing MonitorExtension. Displays the label in the Wisdom
     * Monitor side bar.
     * @return  the name of the label.
     */
    @Override
    public String label() {
        return "Extension Manager";
    }

    /**
     * Method required from implementing MonitorExtension.
     * @return  url of the method to be accessed via the Monitor.
     */
    @Override
    public String url() {
        return "/monitor/registry/manage";
    }

    /**
     * Method required from implementing MonitorExtension. Displays the category in the Wisdom
     * Monitor side bar.
     * @return  the name of the category.
     */
    @Override
    public String category() {
        return "Documentation";
    }
}