org.apache.openmeetings.servlet.outputhandler.ScreenController.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openmeetings.servlet.outputhandler.ScreenController.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
package org.apache.openmeetings.servlet.outputhandler;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.apache.openmeetings.OpenmeetingsVariables;
import org.apache.openmeetings.data.basic.FieldManager;
import org.apache.openmeetings.data.basic.SessiondataDao;
import org.apache.openmeetings.data.basic.dao.ConfigurationDao;
import org.apache.openmeetings.persistence.beans.room.Client;
import org.apache.openmeetings.session.ISessionManager;
import org.apache.openmeetings.utils.OmFileHelper;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ScreenController {
    private static final Logger log = Red5LoggerFactory.getLogger(ScreenController.class,
            OpenmeetingsVariables.webAppRootKey);

    @Autowired
    private ISessionManager sessionManager;
    @Autowired
    public SessiondataDao sessiondataDao;
    @Autowired
    public ConfigurationDao configurationDao;
    @Autowired
    public FieldManager fieldManager;

    private enum ConnectionType {
        rtmp, rtmps, rtmpt
    }

    private String getLabels(Long language_id, int... ids) {
        StringBuilder result = new StringBuilder();
        boolean delim = false;
        for (int id : ids) {
            if (delim) {
                result.append(';');
            }
            result.append(fieldManager.getFieldByIdAndLanguage((long) id, language_id).getValue());
            delim = true;
        }
        return result.toString();
    }

    @RequestMapping(value = "/screen.upload")
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) {
        try {
            String sid = request.getParameter("sid");
            Long users_id = sessiondataDao.checkSession(sid);
            String publicSID = request.getParameter("publicSID");
            if (publicSID == null) {
                throw new Exception("publicSID is empty: " + publicSID);
            }
            if (users_id == 0) {
                //checkSession will return 0 in case of invalid session
                throw new Exception("Request from invalid user " + users_id);
            }

            String domain = request.getParameter("domain");
            if (domain == null) {
                throw new Exception("domain is empty: " + domain);
            }

            String languageAsString = request.getParameter("languageAsString");
            if (languageAsString == null) {
                throw new Exception("languageAsString is empty: " + languageAsString);
            }
            Long language_id = Long.parseLong(languageAsString);

            String rtmphostlocal = request.getParameter("rtmphostlocal");
            if (rtmphostlocal == null) {
                throw new Exception("rtmphostlocal is empty: " + rtmphostlocal);
            }

            String red5httpport = request.getParameter("red5httpport");
            if (red5httpport == null) {
                throw new Exception("red5httpport is empty: " + red5httpport);
            }

            String httpRootKey = request.getParameter("httpRootKey");
            if (httpRootKey == null) {
                throw new Exception("httpRootKey is empty could not start sharer");
            }

            String baseURL = request.getScheme() + "://" + rtmphostlocal + ":" + red5httpport + httpRootKey;

            log.debug("httpRootKey " + httpRootKey);
            log.debug("language_id :: " + language_id);
            String label_sharer = "Sharer";

            try {
                label_sharer = getLabels(language_id, 730, 731, 732, 733, 734, 735, 737, 738, 739, 740, 741, 742,
                        844, 869, 870, 871, 872, 878, 1089, 1090, 1091, 1092, 1093, 1465, 1466, 1467, 1468, 1469,
                        1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477);
            } catch (Exception e) {
                log.error("Error resolving Language labels : ", e);
            }
            log.debug("Creating JNLP Template for TCP solution");

            //libs
            StringBuilder libs = new StringBuilder();
            File screenShareDir = OmFileHelper.getScreenSharingDir();
            for (File jar : screenShareDir.listFiles(new FileFilter() {
                public boolean accept(File pathname) {
                    return pathname.getName().endsWith(".jar");
                }
            })) {
                libs.append("\t\t<jar href=\"").append(jar.getName()).append("\"/>\n");
            }
            log.debug("RTMP Sharer labels :: " + label_sharer);

            ConnectionType conType = ConnectionType.valueOf(request.getParameter("connectionType"));

            String startUpClass;
            switch (conType) {
            case rtmp:
                startUpClass = "org.apache.openmeetings.screen.webstart.RTMPScreenShare";
                break;
            case rtmps:
                startUpClass = "org.apache.openmeetings.screen.webstart.RTMPSScreenShare";
                break;
            case rtmpt:
                startUpClass = "org.apache.openmeetings.screen.webstart.RTMPTScreenShare";
                break;
            default:
                throw new Exception("Unknown connection type");
            }

            String orgIdAsString = request.getParameter("organization_id");
            if (orgIdAsString == null) {
                throw new Exception("orgIdAsString is empty could not start sharer");
            }

            String port = request.getParameter("port");
            if (port == null) {
                throw new Exception("port is empty: ");
            }
            Client rc = sessionManager.getClientByPublicSID(publicSID, false, null);
            if (rc == null) {
                throw new Exception("port is empty: ");
            }
            Long roomId = rc.getRoom_id();
            boolean allowRecording = rc.getAllowRecording() && (0 == sessionManager.getRecordingCount(roomId));
            boolean allowPublishing = (0 == sessionManager.getPublishingCount(roomId));

            Context ctx = new VelocityContext();
            ctx.put("APP_NAME", configurationDao.getAppName());
            ctx.put("PUBLIC_SID", publicSID);
            ctx.put("LABELSHARER", label_sharer);
            addKeystore(ctx);
            ctx.put("LIBRARIES", libs);
            ctx.put("organization_id", orgIdAsString);
            ctx.put("startUpClass", startUpClass);
            ctx.put("codebase", baseURL + OmFileHelper.SCREENSHARING_DIR);
            ctx.put("red5-host", rtmphostlocal);
            ctx.put("red5-app", OpenmeetingsVariables.webAppRootKey + "/" + roomId);
            ctx.put("default_quality_screensharing",
                    configurationDao.getConfValue("default.quality.screensharing", String.class, "1"));
            //invited guest does not have valid user_id (have user_id == -1)
            ctx.put("user_id", users_id);
            ctx.put("port", port);
            ctx.put("allowRecording", allowRecording);
            ctx.put("allowPublishing", allowPublishing);

            String requestedFile = StringUtils.deleteWhitespace(domain + "_" + roomId) + ".jnlp";
            response.setContentType("application/x-java-jnlp-file");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "Inline; filename=\"" + requestedFile + "\"");

            VelocityEngine ve = new VelocityEngine();
            ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
            ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());

            ve.mergeTemplate("screenshare.vm", "UTF-8", ctx, response.getWriter());
        } catch (Exception er) {
            log.error("[ScreenController]", er);
        }
    }

    private StringBuilder addArgument(StringBuilder sb, Object arg) {
        return sb.append("\t\t<argument>").append(arg).append("</argument>\n");
    }

    private void addKeystore(Context ctx) {
        log.debug("RTMP Sharer Keystore :: start");
        StringBuilder sb = new StringBuilder();
        FileInputStream fis = null;
        try {
            File conf = new File(OmFileHelper.getRootDir(), "conf");

            File keyStore = new File(conf, "keystore.screen");
            if (keyStore.exists()) {
                Properties red5Props = new Properties();
                red5Props.load(new FileInputStream(new File(conf, "red5.properties")));

                byte keyBytes[] = new byte[(int) keyStore.length()];
                fis = new FileInputStream(keyStore);
                fis.read(keyBytes);

                sb = addArgument(addArgument(sb, Hex.encodeHexString(keyBytes)),
                        red5Props.getProperty("rtmps.keystorepass"));

                /*
                KeyStore ksIn = KeyStore.getInstance(KeyStore.getDefaultType());
                ksIn.load(new FileInputStream(keyStore), red5Props.getProperty("rtmps.keystorepass").toCharArray());
                ByteArrayInputStream bin = new ByteArrayInputStream()
                    
                byte fileContent[] = new byte[(int)file.length()];
                sb = addArgument(sb, Object arg)
                ctx.put("$KEYSTORE", users_id);
                /*
                KeyStore ksOut = KeyStore.getInstance(KeyStore.getDefaultType());
                for (Certificate cert : ksIn.getCertificateChain("red5")) {
                   PublicKey pub = cert.getPublicKey();
                   TrustedCertificateEntry tce = new TrustedCertificateEntry(cert);
                   tce.
                }
                */
            }
        } catch (Exception e) {
            //no op
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    // no op
                }
            }
        }
        ctx.put("KEYSTORE", sb);
    }
}