org.olat.course.db.CustomDBController.java Source code

Java tutorial

Introduction

Here is the source code for org.olat.course.db.CustomDBController.java

Source

/**
 * OLAT - Online Learning and Training<br>
 * http://www.olat.org
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); <br>
 * you may not use this file except in compliance with the License.<br>
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing,<br>
 * software distributed under the License is distributed on an "AS IS" BASIS, <br>
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
 * See the License for the specific language governing permissions and <br>
 * limitations under the License.
 * <p>
 * Copyright (c) frentix GmbH<br>
 * http://www.frentix.com<br>
 * <p>
 */
package org.olat.course.db;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.WorkbookUtil;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.helpers.Settings;
import org.olat.core.id.User;
import org.olat.core.id.UserConstants;
import org.olat.core.util.ExportUtil;
import org.olat.core.util.StringHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.SyncerExecutor;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.nodes.CourseNode;
import org.olat.course.properties.CoursePropertyManager;
import org.olat.course.tree.CourseEditorTreeNode;
import org.olat.properties.Property;
import org.olat.restapi.security.RestSecurityHelper;
import org.olat.user.UserManager;

/**
 * 
 * Description:<br>
 * Controller to manage a custom DB, export, delete...
 * 
 * <P>
 * Initial Date:  7 apr. 2010 <br>
 * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
 */
public class CustomDBController extends FormBasicController {

    private FormLink addDatabase;
    private List<FormLink> resetDbs = new ArrayList<FormLink>();
    private List<FormLink> deleteDbs = new ArrayList<FormLink>();
    private List<FormLink> exportDbs = new ArrayList<FormLink>();
    private FormLayoutContainer dbListLayout;

    private CustomDBAddController addController;
    private CloseableModalController cmc;

    private final Long courseKey;

    private final CourseDBManager courseDbManager;

    public CustomDBController(UserRequest ureq, WindowControl wControl, Long courseKey) {
        super(ureq, wControl, LAYOUT_VERTICAL);
        this.courseKey = courseKey;
        courseDbManager = CoreSpringFactory.getImpl(CourseDBManager.class);
        initForm(ureq);
    }

    @Override
    protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
        setFormTitle("customDb.custom_db");

        dbListLayout = FormLayoutContainer.createDefaultFormLayout("dbListLayout", getTranslator());
        formLayout.add(dbListLayout);
        updateDBList(dbListLayout);

        addDatabase = uifactory.addFormLink("command.new_db", formLayout, Link.BUTTON);
    }

    public void updateUI() {
        FormItem[] items = new FormItem[dbListLayout.getFormComponents().size()];
        items = dbListLayout.getFormComponents().values().toArray(items);
        for (FormItem item : items) {
            dbListLayout.remove(item);
        }
        initialPanel.setDirty(true);
        updateDBList(dbListLayout);
    }

    private void updateDBList(FormItemContainer formLayout) {
        ICourse course = CourseFactory.loadCourse(courseKey);
        CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
        CourseNode rootNode = ((CourseEditorTreeNode) course.getEditorTreeModel().getRootNode()).getCourseNode();
        Property p = cpm.findCourseNodeProperty(rootNode, null, null, CustomDBMainController.CUSTOM_DB);

        List<String> databases = new ArrayList<>();
        if (p != null && p.getTextValue() != null) {
            String[] dbs = p.getTextValue().split(":");
            for (String db : dbs) {
                databases.add(db);
            }
        }

        List<String> currentlyUsed = courseDbManager.getUsedCategories(course);
        for (String db : currentlyUsed) {
            if (!databases.contains(db)) {
                databases.add(db);
            }
        }

        int count = 0;
        for (String db : databases) {
            if (!StringHelper.containsNonWhitespace(db))
                continue;

            uifactory.addStaticExampleText("category_" + count, "customDb.category", db, formLayout);
            String url = Settings.getServerContextPathURI() + RestSecurityHelper.SUB_CONTEXT + "/repo/courses/"
                    + courseKey + "/db/" + db;
            uifactory.addStaticExampleText("url_" + count, "customDb.url", url, formLayout);

            final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout_" + count,
                    getTranslator());
            formLayout.add(buttonLayout);

            FormLink resetDb = uifactory.addFormLink("db-reset_" + count, "customDb.reset", "customDb.reset",
                    buttonLayout, Link.BUTTON_SMALL);
            resetDb.setUserObject(db);
            FormLink deleteDb = uifactory.addFormLink("db-delete_" + count, "delete", "delete", buttonLayout,
                    Link.BUTTON_SMALL);
            deleteDb.setUserObject(db);
            FormLink exportDb = uifactory.addFormLink("db-export_" + count, "customDb.export", "customDb.export",
                    buttonLayout, Link.BUTTON_SMALL);
            exportDb.setUserObject(db);

            resetDbs.add(resetDb);
            deleteDbs.add(deleteDb);
            exportDbs.add(exportDb);

            count++;
        }
    }

    @Override
    protected void doDispose() {
        //
    }

    @Override
    protected void formOK(UserRequest ureq) {
        //do nothing as default
    }

    @Override
    protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
        if (resetDbs.contains(source)) {
            resetDb((String) source.getUserObject());
        } else if (deleteDbs.contains(source)) {
            deleteDb((String) source.getUserObject());
        } else if (exportDbs.contains(source)) {
            exportDb(ureq, (String) source.getUserObject());
        } else if (source == addDatabase) {
            removeAsListenerAndDispose(addController);
            addController = new CustomDBAddController(ureq, getWindowControl());
            listenTo(addController);
            removeAsListenerAndDispose(cmc);
            cmc = new CloseableModalController(getWindowControl(), translate("close"),
                    addController.getInitialComponent());
            listenTo(cmc);
            cmc.activate();
        }
    }

    @Override
    public void event(UserRequest ureq, Controller source, Event event) {
        if (source == addController) {
            if (event == Event.DONE_EVENT) {
                String category = addController.getCategory();
                addCustomDb(category);
                updateUI();
            }
            cmc.deactivate();
            disposeAddController();
        }
    }

    private void addCustomDb(final String category) {
        final ICourse course = CourseFactory.loadCourse(courseKey);
        CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(course, new SyncerExecutor() {
            @Override
            public void execute() {
                CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
                CourseNode rootNode = ((CourseEditorTreeNode) course.getEditorTreeModel().getRootNode())
                        .getCourseNode();
                Property p = cpm.findCourseNodeProperty(rootNode, null, null, CustomDBMainController.CUSTOM_DB);
                if (p == null) {
                    p = cpm.createCourseNodePropertyInstance(rootNode, null, null, CustomDBMainController.CUSTOM_DB,
                            null, null, null, category);
                    cpm.saveProperty(p);
                } else {
                    String currentDbs = p.getTextValue();
                    p.setTextValue(currentDbs + ":" + category);
                    cpm.updateProperty(p);
                }
            }
        });
    }

    private void disposeAddController() {
        removeAsListenerAndDispose(addController);
        removeAsListenerAndDispose(cmc);
        addController = null;
        cmc = null;
    }

    private void resetDb(String category) {
        CourseDBManager dbManager = CourseDBManager.getInstance();
        ICourse course = CourseFactory.loadCourse(courseKey);
        dbManager.reset(course, category);
    }

    private void deleteDb(String category) {
        CourseDBManager dbManager = CourseDBManager.getInstance();
        ICourse course = CourseFactory.loadCourse(courseKey);
        dbManager.reset(course, category);
        deleteCustomDb(course, category);
        updateUI();
    }

    private void exportDb(UserRequest ureq, String category) {
        ICourse course = CourseFactory.loadCourse(courseKey);
        byte[] content = getDbsContent(course.getCourseTitle(), category);
        if (content == null) {
            showError("customDb.export.failed");
        } else {
            UserManager um = UserManager.getInstance();
            String charset = um.getUserCharset(ureq.getIdentity());
            String fileName = ExportUtil.createFileNameWithTimeStamp("DBS_" + course.getCourseTitle(), "xls");
            MediaResource export = new CourseDBMediaResource(charset, fileName, content);
            ureq.getDispatchResult().setResultingMediaResource(export);
        }
    }

    private byte[] getDbsContent(String courseTitle, String category) {
        ICourse course = CourseFactory.loadCourse(courseKey);
        List<CourseDBEntry> content = CourseDBManager.getInstance().getValues(course, null, category, null);

        Workbook wb = new HSSFWorkbook();
        CellStyle headerCellStyle = getHeaderCellStyle(wb);
        String saveTitle = WorkbookUtil.createSafeSheetName(courseTitle);
        Sheet exportSheet = wb.createSheet(saveTitle);

        //create the headers
        Row headerRow = exportSheet.createRow(0);
        Cell cell = headerRow.createCell(0);
        cell.setCellValue(translate("customDb.category"));
        cell.setCellStyle(headerCellStyle);

        cell = headerRow.createCell(1);
        cell.setCellValue(translate("customDb.entry.identity"));
        cell.setCellStyle(headerCellStyle);

        cell = headerRow.createCell(2);
        cell.setCellValue(translate("customDb.entry.name"));
        cell.setCellStyle(headerCellStyle);

        cell = headerRow.createCell(3);
        cell.setCellValue(translate("customDb.entry.value"));
        cell.setCellStyle(headerCellStyle);

        int count = 0;
        for (CourseDBEntry entry : content) {
            User user = entry.getIdentity().getUser();
            String name = user.getProperty(UserConstants.FIRSTNAME, null) + " "
                    + user.getProperty(UserConstants.LASTNAME, null);

            Row dataRow = exportSheet.createRow(++count);
            Cell dataCell = dataRow.createCell(0);
            dataCell.setCellValue(entry.getCategory());

            dataCell = dataRow.createCell(1);
            dataCell.setCellValue(name);

            if (StringHelper.containsNonWhitespace(entry.getName())) {
                dataCell = dataRow.createCell(2);
                dataCell.setCellValue(entry.getName());
            }

            if (entry.getValue() != null) {
                dataCell = dataRow.createCell(3);
                dataCell.setCellValue(entry.getValue().toString());
            }
        }

        try {
            ByteArrayOutputStream fos = new ByteArrayOutputStream();
            wb.write(fos);
            fos.flush();
            return fos.toByteArray();
        } catch (IOException e) {
            logError("", e);
        }
        return null;
    }

    private CellStyle getHeaderCellStyle(final Workbook wb) {
        CellStyle cellStyle = wb.createCellStyle();
        Font boldFont = wb.createFont();
        boldFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
        cellStyle.setFont(boldFont);
        return cellStyle;
    }

    private void deleteCustomDb(final ICourse course, final String category) {
        CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(course, new SyncerExecutor() {
            @Override
            public void execute() {
                CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
                CourseNode rootNode = ((CourseEditorTreeNode) course.getEditorTreeModel().getRootNode())
                        .getCourseNode();
                Property p = cpm.findCourseNodeProperty(rootNode, null, null, CustomDBMainController.CUSTOM_DB);
                if (p != null && p.getTextValue() != null) {
                    String[] dbs = p.getTextValue().split(":");
                    StringBuilder currentDbs = new StringBuilder();
                    for (String db : dbs) {
                        if (!db.equals(category)) {
                            currentDbs.append(db).append(':');
                        }
                    }
                    p.setTextValue(currentDbs.toString());
                    cpm.updateProperty(p);
                }
            }
        });
    }
}