controllers.modules.AspectLexBuilder.java Source code

Java tutorial

Introduction

Here is the source code for controllers.modules.AspectLexBuilder.java

Source

/*
 * Sentilab SARE: a Sentiment Analysis Research Environment
 * Copyright (C) 2013 Sabanci University Sentilab
 * http://sentilab.sabanciuniv.edu
 * 
 * This file is part of SARE.
 * 
 * SARE 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.
 *  
 * SARE 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 SARE. If not, see <http://www.gnu.org/licenses/>.
 */

package controllers.modules;

import static controllers.base.SareTransactionalAction.*;
import static controllers.base.SessionedAction.*;
import static models.base.ViewModel.*;

import java.util.*;

import javax.annotation.Nullable;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.*;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;

import com.google.common.base.*;
import com.google.common.collect.*;

import play.api.templates.Html;
import play.libs.Json;
import play.mvc.*;
import play.mvc.Http.MultipartFormData;
import play.mvc.Http.MultipartFormData.FilePart;
import views.html.tags.*;
import models.base.ViewModel;
import models.document.LexiconBuilderDocumentTokenModel;
import models.document.PersistentDocumentModel;
import models.documentStore.*;
import controllers.CollectionsController;
import controllers.base.*;
import controllers.modules.base.Module;
import edu.sabanciuniv.sentilab.sare.controllers.aspect.AspectLexiconFactory;
import edu.sabanciuniv.sentilab.sare.controllers.entitymanagers.*;
import edu.sabanciuniv.sentilab.sare.models.aspect.*;
import edu.sabanciuniv.sentilab.sare.models.base.document.*;
import edu.sabanciuniv.sentilab.sare.models.base.documentStore.*;
import edu.sabanciuniv.sentilab.utils.UuidUtils;
import edu.sabanciuniv.sentilab.utils.text.nlp.base.LinguisticToken;

@With(SareTransactionalAction.class)
@Module.Requireses({ @Module.Requires({ DocumentCorpusModel.class, AspectLexiconModel.class }),
        @Module.Requires(DocumentCorpusModel.class), @Module.Requires(AspectLexiconModel.class), @Module.Requires })
public class AspectLexBuilder extends Module {

    public static List<PersistentDocumentStoreModel> getLexica(DocumentCorpusModel corpus) {
        LexiconController lexiconController = new LexiconController();
        List<PersistentDocumentStoreModel> lexica = Lists.newArrayList();
        for (String lexiconId : lexiconController.getAllLexica(em(), getUsername(), AspectLexicon.class)) {
            AspectLexicon lexicon = fetchResource(UuidUtils.create(lexiconId), AspectLexicon.class);
            if (corpus == null || (lexicon.getBaseStore() != null && UuidUtils.normalize(corpus.id)
                    .equals(UuidUtils.normalize(lexicon.getBaseCorpus().getId())))) {

                PersistentDocumentStoreModel lexiconVM = (PersistentDocumentStoreModel) createViewModel(lexicon);
                lexiconVM.populateSize(em(), lexicon);
                lexica.add(lexiconVM);
            }
        }
        return lexica;
    }

    public static List<PersistentDocumentStoreModel> getLexica() {
        return getLexica(null);
    }

    @Override
    public UUID getId() {
        return UuidUtils.create("454cbf44cf154b0c8792fedc717da027");
    }

    @Override
    public String getDisplayName() {
        return "Build aspect lexicon";
    }

    @Override
    public String getRoute() {
        DocumentCorpusModel corpus = (DocumentCorpusModel) Iterables.find(this.viewModels,
                Predicates.instanceOf(DocumentCorpusModel.class), null);
        AspectLexiconModel lexicon = (AspectLexiconModel) Iterables.find(this.viewModels,
                Predicates.instanceOf(AspectLexiconModel.class), null);
        return controllers.modules.routes.AspectLexBuilder
                .modulePage(corpus != null ? corpus.getIdentifier() : null,
                        lexicon != null ? lexicon.getIdentifier() : null, false)
                .url();
    }

    public static Result modulePage(UUID corpus, UUID lexicon, boolean partial) {
        DocumentCorpus corpusObj = corpus != null ? fetchResource(corpus, DocumentCorpus.class) : null;
        AspectLexicon lexiconObj = lexicon != null ? fetchResource(lexicon, AspectLexicon.class) : null;
        if (lexiconObj == null && new LexiconController()
                .getAllLexica(em(), SessionedAction.getUsername(), AspectLexicon.class).size() == 0) {
            create(corpus);
        }

        if (lexiconObj != null && corpusObj == null) {
            corpusObj = lexiconObj.getBaseCorpus();
        }

        DocumentCorpusModel corpusVM = null;
        if (corpusObj != null) {
            corpusVM = (DocumentCorpusModel) createViewModel(corpusObj);
            corpusVM.populateSize(em(), corpusObj);
        }
        AspectLexiconModel lexiconVM = null;
        if (lexiconObj != null) {
            lexiconVM = (AspectLexiconModel) createViewModel(lexiconObj);
            lexiconVM.populateSize(em(), lexiconObj);
        }

        return moduleRender(
                new AspectLexBuilder().setViewModels(Lists.<ViewModel>newArrayList(corpusVM, lexiconVM)),
                aspectLexBuilder.render(corpusVM, lexiconVM, true), partial);
    }

    public static Result create(UUID corpus) {
        return update(corpus, null);
    }

    public static Result update(UUID corpus, UUID lexicon) {
        DocumentCorpus corpusObj = null;
        if (corpus != null) {
            corpusObj = fetchResource(corpus, DocumentCorpus.class);
        }
        AspectLexicon lexiconObj = null;
        if (lexicon != null) {
            lexiconObj = fetchResource(lexicon, AspectLexicon.class);
        }

        AspectLexiconFactory factory = null;

        MultipartFormData formData = request().body().asMultipartFormData();
        if (formData != null) {
            // if we have a multi-part form with a file.
            if (formData.getFiles() != null) {
                // get either the file named "file" or the first one.
                FilePart filePart = ObjectUtils.defaultIfNull(formData.getFile("file"),
                        Iterables.getFirst(formData.getFiles(), null));
                if (filePart != null) {
                    factory = (AspectLexiconFactory) new AspectLexiconFactory().setFile(filePart.getFile())
                            .setFormat(FilenameUtils.getExtension(filePart.getFilename()));
                }
            }
        } else {
            JsonNode json = request().body().asJson();
            if (json != null) {
                AspectLexiconFactoryModel viewModel = Json.fromJson(json, AspectLexiconFactoryModel.class);
                if (viewModel != null) {
                    factory = viewModel.toFactory();

                    if (lexiconObj != null) {
                        if (corpusObj != null && (lexiconObj.getBaseCorpus() == null
                                || !ObjectUtils.equals(lexiconObj.getBaseCorpus(), corpusObj))) {
                            throw new IllegalArgumentException();
                        }
                    }
                } else {
                    throw new IllegalArgumentException();
                }
            } else {
                // if not json, then just create empty options.
                factory = new AspectLexiconFactory();
            }
        }

        if (factory == null) {
            throw new IllegalArgumentException();
        }

        if (lexicon == null && StringUtils.isEmpty(factory.getTitle())) {
            factory.setTitle("Untitled aspect lexicon");
        }

        factory.setBaseStore(corpusObj);
        factory.setOwnerId(SessionedAction.getUsername(ctx()));
        factory.setExistingId(lexicon);
        factory.setEm(em());

        AspectLexiconModel lexiconVM = null;
        lexiconObj = factory.create();
        if (!em().contains(lexiconObj)) {
            em().persist(lexiconObj);

            lexiconVM = (AspectLexiconModel) createViewModel(lexiconObj);
            lexiconVM.populateSize(em(), lexiconObj);
            return created(lexiconVM.asJson());
        }

        em().merge(lexiconObj);

        lexiconVM = (AspectLexiconModel) createViewModel(lexiconObj);
        lexiconVM.populateSize(em(), lexiconObj);
        return ok(lexiconVM.asJson());
    }

    public static Html renderDocumentsView(String corpus, String lexicon) {
        return renderDocumentsView(UuidUtils.create(corpus), UuidUtils.create(lexicon));
    }

    public static Html renderDocumentsView(UUID corpus, UUID lexicon) {
        LexiconBuilderDocumentStore builder = fetchBuilder(corpus, lexicon);
        DocumentCorpus corpusObj = fetchResource(corpus, DocumentCorpus.class);
        AspectLexicon lexiconObj = fetchResource(lexicon, AspectLexicon.class);

        DocumentCorpusModel corpusVM = (DocumentCorpusModel) createViewModel(corpusObj);
        corpusVM.populateSize(em(), corpusObj);

        AspectLexiconModel lexiconVM = (AspectLexiconModel) createViewModel(lexiconObj);
        lexiconVM.populateSize(em(), lexiconObj);

        return documentSlider.render(corpusVM, lexiconVM, corpusObj.getLinguisticProcessor().getBasicPosTags(),
                Lists.newArrayList(Splitter.on("|")
                        .split(StringUtils.defaultString(builder.getProperty("emphasizedTags", String.class)))));
    }

    public static Result documentsView(UUID corpus, UUID lexicon) {
        return ok(renderDocumentsView(corpus, lexicon));
    }

    public static Result lexiconView(UUID lexicon) {
        AspectLexicon lexiconObj = fetchResource(lexicon, AspectLexicon.class);
        AspectLexiconModel lexiconVM = (AspectLexiconModel) createViewModel(lexiconObj);
        lexiconVM.populateSize(em(), lexiconObj);
        return ok(aspectLexicon.render(lexiconVM, true));
    }

    private static LexiconBuilderDocumentStore fetchBuilder(UUID corpus, UUID lexicon) {
        DocumentCorpus corpusObj = fetchResource(corpus, DocumentCorpus.class);
        AspectLexicon lexiconObj = fetchResource(lexicon, AspectLexicon.class);
        LexiconBuilderController controller = new LexiconBuilderController();
        LexiconBuilderDocumentStore builder = controller.findBuilder(em(), corpusObj, lexiconObj);
        if (builder == null) {
            builder = (LexiconBuilderDocumentStore) new LexiconBuilderDocumentStore(corpusObj, lexiconObj)
                    .setOwnerId(getUsername());
            em().persist(builder);
        } else {
            controller.refreshBuilder(em(), builder);
        }

        return builder;
    }

    private static LexiconBuilderDocument fetchDocument(LexiconBuilderDocumentStore builder, Long rank) {
        if (rank < 0) {
            rank = null;
        }

        LexiconBuilderDocument document = new LexiconBuilderController().getDocument(em(), builder, rank);
        if (document != null && document.getFullTextDocument() != null) {
            TokenizingOptions tokenizingOptions = document.getFullTextDocument().getTokenizingOptions();
            document.getFullTextDocument().setTokenizingOptions(tokenizingOptions.setLemmatized(true));
        }
        return document;
    }

    public static Result getDocument(UUID corpus, UUID lexicon, final String emphasis, Long rank) {
        final LexiconBuilderDocumentStore builder = fetchBuilder(corpus, lexicon);
        final AspectLexicon lexiconObj = (AspectLexicon) builder.getLexicon();
        final LexiconBuilderController controller = new LexiconBuilderController();

        LexiconBuilderDocument document = fetchDocument(builder, rank);
        if (document != null && document.getFullTextDocument() != null) {
            List<LexiconBuilderDocumentTokenModel> tokens = Lists
                    .newArrayList(Iterables.transform(document.getFullTextDocument().getParsedContent().getTokens(),
                            new Function<LinguisticToken, LexiconBuilderDocumentTokenModel>() {
                                @Override
                                @Nullable
                                public LexiconBuilderDocumentTokenModel apply(@Nullable LinguisticToken input) {
                                    LexiconBuilderDocumentTokenModel model = new LexiconBuilderDocumentTokenModel(
                                            input);
                                    model.emphasized = input.getPosTag().is(emphasis);
                                    if (model.emphasized) {
                                        model.seen = controller.isSeenToken(em(), builder, input.toString());

                                        AspectExpression expression = lexiconObj.findExpression(input.getLemma(),
                                                true);
                                        if (expression == null) {
                                            expression = lexiconObj.findExpression(input.getText(), true);
                                        }
                                        if (expression != null && expression.getAspect() != null) {
                                            model.aspect = (AspectLexiconModel) createViewModel(
                                                    expression.getAspect());
                                        }
                                    }
                                    return model;
                                }
                            }));
            ObjectNode json = (ObjectNode) createViewModel(document.getBaseDocument()).asJson();
            json.put("enhancedContent", enhancedDocument.render(tokens, emphasis).body());
            json.put("rank", document.getRank());
            return ok(json);
        }

        return notFoundEntity(ObjectUtils.toString(rank));
    }

    public static Result seeDocument(UUID corpus, UUID lexicon, String emphasis, Long rank) {
        LexiconBuilderDocumentStore builder = fetchBuilder(corpus, lexicon);
        LexiconBuilderDocument document = fetchDocument(builder, rank);

        if (document != null && document.getFullTextDocument() != null) {
            new LexiconBuilderController().setSeenDocument(em(), document, emphasis);

            builder.setProperty("emphasizedTags", emphasis);
            em().merge(builder);

            return ok(createViewModel(document.getFullTextDocument()).asJson());
        }

        return notFoundEntity(ObjectUtils.toString(rank));
    }

    public static Result getAspects(UUID lexicon) {
        AspectLexicon lexiconObj = fetchResource(lexicon, AspectLexicon.class);
        List<AspectLexiconModel> aspects = Lists.newArrayList(
                Iterables.transform(lexiconObj.getAspects(), new Function<AspectLexicon, AspectLexiconModel>() {
                    @Override
                    @Nullable
                    public AspectLexiconModel apply(@Nullable AspectLexicon input) {
                        return (AspectLexiconModel) createViewModel(input);
                    }
                }));

        return ok(Json.toJson(aspects));
    }

    public static Result getAspect(UUID lexicon, String aspect, boolean recursive) {
        AspectLexicon lexiconObj = null;
        AspectLexicon aspectObj = null;

        if (lexicon != null) {
            lexiconObj = fetchResource(lexicon, AspectLexicon.class);
        }
        if (UuidUtils.isUuid(aspect)) {
            aspectObj = fetchResourceQuietly(UuidUtils.create(aspect), AspectLexicon.class);
            if (aspectObj != null && lexiconObj != null
                    && !ObjectUtils.equals(aspectObj.getParentAspect(), lexiconObj)) {
                throw new IllegalArgumentException();
            }
        }

        if (aspectObj == null && lexiconObj != null) {
            aspectObj = lexiconObj.findAspect(aspect, recursive);
        }

        if (aspectObj == null) {
            return notFoundEntity(aspect);
        }

        return ok(createViewModel(aspectObj).asJson());
    }

    @BodyParser.Of(play.mvc.BodyParser.Json.class)
    public static Result addAspect(UUID lexicon) {
        AspectLexicon lexiconObj = fetchResource(lexicon, AspectLexicon.class);
        JsonNode aspectJson = request().body().asJson();
        AspectLexiconModel aspect = aspectJson == null ? new AspectLexiconModel()
                : Json.fromJson(aspectJson, AspectLexiconModel.class);

        // if no title, generate an unused one.
        if (StringUtils.isEmpty(aspect.title)) {
            int count = 0;
            while (lexiconObj.hasAspect("Aspect " + ++count))
                ;
            aspect.title = "Aspect " + count;
        }

        AspectLexicon aspectObj = lexiconObj.addAspect(aspect.title);
        if (aspectObj == null) {
            throw new IllegalArgumentException();
        }

        em().persist(aspectObj);

        return created(createViewModel(aspectObj).asJson());
    }

    @BodyParser.Of(play.mvc.BodyParser.Json.class)
    public static Result updateExpression(UUID aspect, UUID expression) {
        AspectLexicon aspectObj = null;
        AspectExpression expressionObj = fetchResource(expression, AspectExpression.class);
        JsonNode updatedExpressionNode = request().body().asJson();

        if (aspect != null) {
            aspectObj = fetchResource(aspect, AspectLexicon.class);
            if (!ObjectUtils.equals(expressionObj.getAspect(), aspectObj)
                    && !aspectObj.migrateExpression(expressionObj)) {
                throw new IllegalArgumentException();
            }
        } else if (expressionObj.getAspect() != null) {
            aspectObj = expressionObj.getAspect();
        } else {
            throw new IllegalArgumentException();
        }

        if (updatedExpressionNode != null) {
            PersistentDocumentModel updatedExpression = Json.fromJson(updatedExpressionNode,
                    PersistentDocumentModel.class);
            expressionObj = aspectObj.updateExpression(expressionObj.getContent(), updatedExpression.content);
            if (expressionObj == null) {
                throw new IllegalArgumentException();
            }
        }

        em().merge(expressionObj);
        return ok(createViewModel(expressionObj).asJson());
    }

    @BodyParser.Of(play.mvc.BodyParser.Json.class)
    public static Result updateAspect(UUID lexicon, UUID aspect) {
        AspectLexicon lexiconObj = null;
        AspectLexicon aspectObj = fetchResource(aspect, AspectLexicon.class);
        JsonNode updatedAspectNode = request().body().asJson();

        if (lexicon != null) {
            lexiconObj = fetchResource(lexicon, AspectLexicon.class);

            if (!ObjectUtils.equals(aspectObj.getParentAspect(), lexiconObj)
                    && !lexiconObj.migrateAspect(aspectObj)) {
                throw new IllegalArgumentException();
            }
        } else if (aspectObj.getParentAspect() != null) {
            lexiconObj = aspectObj.getParentAspect();
        } else {
            throw new IllegalArgumentException();
        }

        if (updatedAspectNode != null) {
            AspectLexiconModel updatedAspect = Json.fromJson(updatedAspectNode, AspectLexiconModel.class);
            aspectObj = lexiconObj.updateAspect(aspectObj.getTitle(), updatedAspect.title);
            if (aspectObj == null) {
                throw new IllegalArgumentException();
            }
        }

        em().merge(aspectObj);

        return ok(createViewModel(aspectObj).asJson());
    }

    public static Result deleteAspect(UUID lexicon, UUID aspect) {
        if (lexicon != null) {
            AspectLexicon lexiconObj = fetchResource(lexicon, AspectLexicon.class);
            AspectLexicon aspectObj = fetchResource(aspect, AspectLexicon.class);
            if (aspectObj.getParentAspect() != null
                    && ObjectUtils.equals(aspectObj.getParentAspect(), lexiconObj)) {
                aspectObj = lexiconObj.removeAspect(aspectObj.getTitle());
                em().remove(aspectObj);

                return ok(createViewModel(aspectObj).asJson());
            } else {
                throw new IllegalArgumentException();
            }
        }

        return CollectionsController.delete(aspect);
    }

    public static Result getExpressions(UUID aspect) {
        AspectLexicon aspectObj = fetchResource(aspect, AspectLexicon.class);
        List<PersistentDocumentModel> expressions = Lists.newArrayList(Iterables
                .transform(aspectObj.getExpressions(), new Function<AspectExpression, PersistentDocumentModel>() {
                    @Override
                    @Nullable
                    public PersistentDocumentModel apply(@Nullable AspectExpression input) {
                        return (PersistentDocumentModel) createViewModel(input);
                    }
                }));

        return ok(Json.toJson(expressions));
    }

    public static Result getExpression(UUID aspect, String expression, boolean recursive) {
        AspectLexicon aspectObj = null;
        AspectExpression expressionObj = null;

        if (aspect != null) {
            aspectObj = fetchResource(aspect, AspectLexicon.class);
        }
        if (UuidUtils.isUuid(expression)) {
            expressionObj = fetchResourceQuietly(UuidUtils.create(expression), AspectExpression.class);
            if (expressionObj != null && aspectObj != null
                    && !ObjectUtils.equals(expressionObj.getAspect(), aspectObj)) {
                throw new IllegalArgumentException();
            }
        }

        if (expressionObj == null && aspectObj != null) {
            expressionObj = aspectObj.findExpression(expression, recursive);
        }

        if (expressionObj == null) {
            return notFoundEntity(UuidUtils.normalize(expression));
        }
        return ok(createViewModel(expressionObj).asJson());
    }

    @BodyParser.Of(play.mvc.BodyParser.Json.class)
    public static Result addExpression(UUID aspect) {
        AspectLexicon aspectObj = fetchResource(aspect, AspectLexicon.class);
        JsonNode expressionJson = request().body().asJson();
        PersistentDocumentModel expression = expressionJson == null ? new PersistentDocumentModel()
                : Json.fromJson(expressionJson, PersistentDocumentModel.class);

        // if no content, generate an unused one.
        if (StringUtils.isEmpty(expression.content)) {
            int count = 0;
            while (aspectObj.hasExpression("Keyword " + ++count))
                ;
            expression.content = "Keyword " + count;
        }

        AspectExpression expressionObj = aspectObj.addExpression(expression.content);
        if (expressionObj == null) {
            throw new IllegalArgumentException();
        }

        em().persist(expressionObj);
        return created(createViewModel(expressionObj).asJson());
    }

    public static Result deleteExpression(UUID aspect, UUID expression) {
        AspectExpression expressionObj = fetchResource(expression, AspectExpression.class);
        if (aspect != null) {
            AspectLexicon aspectObj = fetchResource(aspect, AspectLexicon.class);
            if (expressionObj.getAspect() != null && ObjectUtils.equals(expressionObj.getAspect(), aspectObj)) {
                expressionObj = aspectObj.removeExpression(expressionObj.getContent());
            }
        }

        em().remove(expressionObj);
        return ok(createViewModel(expressionObj).asJson());
    }
}