diff --git a/.classpath b/.classpath
index 1321a81..b38515d 100644
--- a/.classpath
+++ b/.classpath
@@ -1,13 +1,45 @@
-
-
+
-
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index c055778..2573375 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,23 +1,65 @@
-# Compiled class file
-*.class
+### Eclipse template
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
-# Log file
-*.log
+# External tool builders
+.externalToolBuilders/
-# BlueJ files
-*.ctxt
+# Locally stored "Eclipse launch configurations"
+*.launch
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
-# Package Files #
-#*.jar # in order to include external library
-*.war
-*.ear
-*.zip
-*.tar.gz
-*.rar
+# CDT-specific (C/C++ Development Tooling)
+.cproject
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
-/build/
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+.apt_generated_test/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
+
+# Uncomment this line if you wish to ignore the project description file.
+# Typically, this file would be tracked if it contains build/dependency configurations:
+#.project
+
+/target/
+
+.idea/
diff --git a/.project b/.project
index c48d052..3843021 100644
--- a/.project
+++ b/.project
@@ -11,13 +11,24 @@
- org.eclipse.wst.common.project.facet.core.builder
+ org.eclipse.m2e.core.maven2Builder
- org.eclipse.wst.common.project.facet.core.nature
org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
+ 1683816513702
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index a698e59..93d8913 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,12 +1,17 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.processAnnotations=enabled
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
deleted file mode 100644
index 7c8126d..0000000
--- a/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
+++ /dev/null
@@ -1,5 +0,0 @@
-XDOCLETBUILDERACTIVE=true
-XDOCLETHOME=
-XDOCLETUSEGLOBAL=true
-XDOCLETVERSION=1.2.1
-eclipse.preferences.version=1
diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs
deleted file mode 100644
index b196c64..0000000
--- a/.settings/org.eclipse.ltk.core.refactoring.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index f4ef8aa..0000000
--- a/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/README.md b/README.md
index 61b83d1..c40a7b7 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,28 @@
+# BigBlueButton API Library for Java
-Special note:
-1. This project used Lombok library, if you want to deploy this project, make sure you have Lombok installed. To install, follow the following steps:
- - download from https://projectlombok.org/download
- - go to the location where the Lombar.jar was downloaded, and run "java -jar lombok.jar", change the jar file name to the name of the lombok jar file that you downloaded
- - after you run the previous step, a window should appear, brownse to your editor location (for eclipse, it's where eclipse.exe is located)
- - click install
- - launch Eclipse (or other IDE)
- - add the zomlok library to your project (right click on the properties -> Java Build Path -> Libraries -> add Extenal JARs -> select the lombok jar file that you just downloaded -> Apply and Close
+
+## Description
+
+Official Java Library from BigBlueButton API.
+
+## Requirements
+
+ - JVM 11+
+ - BigBlueButton 2.6+
+
+## Installation
+
+### Using maven
+
+## Maintainers
+
+ - [Ghazi Triki](ghazi.triki@riadvice.tn) from [RIADVICE](https://riadvice.tn)
+
+## Build
+
+```bash
+mvn formatter:format && mvn package
+```
+
+## Support
diff --git a/lib/apache-commons-codec-1.4.jar b/lib/apache-commons-codec-1.4.jar
deleted file mode 100644
index 422c42b..0000000
Binary files a/lib/apache-commons-codec-1.4.jar and /dev/null differ
diff --git a/lib/lombok.jar b/lib/lombok.jar
deleted file mode 100644
index 1728da7..0000000
Binary files a/lib/lombok.jar and /dev/null differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..32594f5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,265 @@
+
+
+
+ 4.0.0
+
+ org.bigbluebutton.api
+ bigbluebutton-api-java
+ 0.1-SNAPSHOT
+
+ BigBlueButton Java API
+ https://bigbluebutton.org
+
+
+
+ GhaziTriki
+ Ghazi Triki
+ ghazi.triki@riadvice.tn
+ RIADVICE
+ htttps://riadvice.tn
+
+ architect
+ developer
+
+ Africa/Tunis
+
+
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+
+
+ 11
+ 2.15.0
+ 2.0.7
+
+
+
+
+ commons-codec
+ commons-codec
+ 1.15
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ true
+
+
+ org.apache.httpcomponents.client5
+ httpclient5
+ 5.2.1
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.9.3
+ test
+
+
+ com.github.javafaker
+ javafaker
+ 1.0.2
+ test
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ 1.4.7
+ test
+
+
+
+
+ src/main/java
+ src/test/java
+
+
+ maven-clean-plugin
+ 3.2.0
+
+
+ maven-resources-plugin
+ 3.3.1
+
+
+ maven-compiler-plugin
+ 3.11.0
+
+ ${java.version}
+ ${java.version}
+
+
+
+ maven-surefire-plugin
+ 3.1.0
+
+
+ --illegal-access=permit
+
+ true
+ 2
+ true
+ ${surefireArgLine}
+
+
+
+ maven-jar-plugin
+ 3.3.0
+
+
+ maven-install-plugin
+ 3.1.1
+
+
+ maven-deploy-plugin
+ 3.1.1
+
+
+ maven-site-plugin
+ 3.12.1
+
+
+ maven-project-info-reports-plugin
+ 3.4.3
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.20.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+
+
+ java
+
+
+
+
+
+ net.revelc.code.formatter
+ formatter-maven-plugin
+ 2.22.0
+
+
+
+
+
+
+
+
+ ${java.version}
+ ${java.version}
+ ${java.version}
+ LF
+ UTF-8
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ 4.7.3.4
+
+
+ com.github.spotbugs
+ spotbugs
+ 4.7.3.4
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.10
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+ ${project.build.directory}/coverage-reports/jacoco.exec
+ surefireArgLine
+
+
+
+ default-report
+ test
+
+ report
+
+
+
+ ${project.build.directory}/coverage-reports/jacoco.exec
+
+ ${project.reporting.outputDirectory}/jacoco
+
+
+
+ default-check
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ COMPLEXITY
+ COVEREDRATIO
+ 0.75
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BigBlueButton/api/BBBException.java b/src/BigBlueButton/api/BBBException.java
deleted file mode 100644
index 58c613c..0000000
--- a/src/BigBlueButton/api/BBBException.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package BigBlueButton.api;
-
-/**
- * Exception generated while communicating with BBB server
- *
- * see https://github.com/sakaicontrib/bbb-tool/blob/master/api/src/java/org/sakaiproject/bbb/api/BBBException.java
- */
-public class BBBException extends Exception {
- private static final long serialVersionUID = 2421100107566638321L;
-
- public static final String MESSAGEKEY_HTTPERROR = "httpError";
- public static final String MESSAGEKEY_NOTFOUND = "notFound";
- public static final String MESSAGEKEY_NOACTION = "noActionSpecified";
- public static final String MESSAGEKEY_IDNOTUNIQUE = "idNotUnique";
- public static final String MESSAGEKEY_NOTSTARTED = "notStarted";
- public static final String MESSAGEKEY_ALREADYENDED = "alreadyEnded";
- public static final String MESSAGEKEY_INTERNALERROR = "internalError";
- public static final String MESSAGEKEY_UNREACHABLE = "unreachableServerError";
- public static final String MESSAGEKEY_INVALIDRESPONSE = "invalidResponseError";
- public static final String MESSAGEKEY_GENERALERROR = "generalError";
-
- private String messageKey;
-
- public BBBException(String messageKey, String message, Throwable cause) {
- super(message, cause);
- this.messageKey = messageKey;
- }
-
- public BBBException(String messageKey, String message) {
- super(message);
- this.messageKey = messageKey;
- }
-
- public String getMessageKey() {
- return messageKey;
- }
-
- public void setMessageKey(String messageKey) {
- this.messageKey = messageKey;
- }
-
- public String getPrettyMessage() {
- String _message = getMessage();
- String _messageKey = getMessageKey();
-
- StringBuilder pretty = new StringBuilder();
- if(_message != null) {
- pretty.append(_message);
- }
- if(_messageKey != null && !"".equals(_messageKey.trim())) {
- pretty.append(" (");
- pretty.append(_messageKey);
- pretty.append(")");
- }
- return pretty.toString();
- }
-
-}
\ No newline at end of file
diff --git a/src/BigBlueButton/api/BBBMeeting.java b/src/BigBlueButton/api/BBBMeeting.java
deleted file mode 100644
index 50e04f2..0000000
--- a/src/BigBlueButton/api/BBBMeeting.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package BigBlueButton.api;
-
-import java.util.Map;
-import java.util.Date;
-import java.util.HashMap;
-
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
-
-/**
- * Object for a BigBlueButton meeting.
- * @author Adrian Fish
- * Based on: https://github.com/sakaicontrib/bbb-tool/blob/master/api/src/java/org/sakaiproject/bbb/api/BBBMeeting.java
- *
- * Last modified by Yunkai Wang
- */
-@Getter @Setter @ToString
-public class BBBMeeting {
- private String name = null;
- private String meetingID;
- private String attendeePW = null;
- private String moderatorPW = null;
- private String dialNumber = null;
- private String voiceBridge = null;
- private String webVoice = null;
- private String logoutURL = null;
- private Boolean record = null;
- private Long duration = null;
-
- // user cannot directly modify this field
- @Setter (AccessLevel.NONE)
- private Map meta = new HashMap();
- private String moderatorOnlyMessage = null;
- private Boolean autoStartRecording = null;
- private Boolean allowStartStopRecording = null;
- private Boolean webcamsOnlyForModerator = null;
- private String logo = null;
- private String copyright = null;
- private Boolean muteOnStart = null;
- private String welcome = null;
- private Date startDate = null;
- private Date endDate = null;
-
- public BBBMeeting(String meetingID) {
- this.meetingID = meetingID;
- }
-
- public void addMeta(String key, String value) {
- meta.put(key, value);
- }
-
- public void removeMeta(String key) {
- if (meta.containsKey(key))
- meta.remove(key);
- }
-}
diff --git a/src/BigBlueButton/impl/BBBAPI.java b/src/BigBlueButton/impl/BBBAPI.java
deleted file mode 100644
index 690013d..0000000
--- a/src/BigBlueButton/impl/BBBAPI.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package BigBlueButton.impl;
-
-import java.util.Map;
-import BigBlueButton.api.BBBException;
-import BigBlueButton.api.BBBMeeting;
-
-/**
- * List of supported API for BigBlueButton, see BigBlueButton doc for more information
- * Based on: https://github.com/sakaicontrib/bbb-tool/blob/master/impl/src/java/org/sakaiproject/bbb/impl/bbbapi/BBBAPI.java
- *
- * Last modified by Yunkai Wang
- */
-public interface BBBAPI {
-
- /**
- * Get the API version of the server
- *
- * @return API version
- */
- public String getAPIVersion();
-
- /**
- * Get the base url of the server
- *
- * @return url
- */
- public String getUrl();
-
- /**
- * Allow user to create meeting
- *
- * @return BBBMeeting object on success, on failure, BBBException is thrown
- * @throws BBBException
- */
- public BBBMeeting createMeeting(final String meetingID) throws BBBException;
- public BBBMeeting createMeeting(final BBBMeeting meeting) throws BBBException;
- public BBBMeeting createMeeting(final BBBMeeting meeting, final BBBModule module) throws BBBException;
-
- /**
- * Check if the meeting is already running
- *
- * @return true if the meeting is running, false otherwise
- * @throws BBBException
- */
- public boolean isMeetingRunning(String meetingID) throws BBBException;
-
- /**
- * Get meeting information corresponds to the given meetingID and role
- *
- * @return Map that contains all meeting information
- * @throws BBBException
- */
- public Map getMeetingInfo(String meetingID, String password) throws BBBException;
- public Map getMeetingInfo(final BBBMeeting meeting) throws BBBException;
-
- /**
- * End the given meeting
- *
- * @return true if the meeting is successfully ended or does not exist, false otherwise
- * @throws BBBException
- */
- public boolean endMeeting(String meetingID, String password) throws BBBException;
- public boolean endMeeting(final BBBMeeting meeting) throws BBBException;
-
- /**
- * Get the url to join the given meeting with the display name and corresponding role type
- *
- * @return url for joining the meeting
- */
- public String getJoinMeetingURL(String meetingID, String password, String userDisplayName);
- public String getJoinMeetingURL(String meetingID, String password, String userDisplayName, String userId);
-
- /**
- * Get the list of all live meetings in server, every parameter like meetingIDs can be a list of meetings but separated
- * by commas(e.g., "id1,id2")
- *
- * @return a map which has a field named meetings, and the value is the list of meeting information
- * @throws BBBException
- */
- public Map getMeetings() throws BBBException;
-
- /**
- * Get the list of recordings that map the given fields
- *
- * @return a map which has a field named recordings, and the value is the list of recording information
- * @throws BBBException
- */
- public Map getRecordings() throws BBBException;
- public Map getRecordings(String meetingIDs) throws BBBException;
- public Map getRecordings(String meetingIDs, String recordIDs) throws BBBException;
- public Map getRecordings(String meetingIDs, String recordIDs, String states) throws BBBException;
- public Map getRecordings(String meetingIDs, String recordIDs, String states, Map meta) throws BBBException;
-
- /**
- * Delete a given recording (or a list of recordings whose ids are separated by commas)
- *
- * @return true if the recording is successfully deleted, exception is thrown on failure
- * @throws BBBException
- */
- public boolean deteteRecordings(String recordIDs) throws BBBException;
-
- /**
- * Publish/unpublish the recording(s)
- *
- * @return true if the recording(s) is successfully published/unpublished, exception is thrown on failure
- * @throws BBBException
- */
- public boolean publishRecordings(String recordIDs, boolean publish) throws BBBException;
-
- /**
- * Update the recording(s)
- *
- * @return true if the recording(s) is successfully updated, exception is thrown on failure
- * @throws BBBException
- */
- public boolean updateRecordings(String recordIDs) throws BBBException;
- public boolean updateRecordings(String recordIDs, Map meta) throws BBBException;
-
- /**
- * Get the default config xml file from the BBB server and save it to the given file path
- *
- * @return true on success, on failure, BBBException is thrown
- * @throws BBBException
- */
- public boolean getDefaultConfigXML(String fileName) throws BBBException;
-
-
- /**
- * Set the config for the given meeting
- *
- * @return true on success, on failure, BBBException is thrown
- * @throws BBBException
- */
- public boolean setConfigXML(String meetingID, String fileName) throws BBBException;
-}
diff --git a/src/BigBlueButton/impl/BBBModule.java b/src/BigBlueButton/impl/BBBModule.java
deleted file mode 100644
index f4dca63..0000000
--- a/src/BigBlueButton/impl/BBBModule.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package BigBlueButton.impl;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import org.apache.commons.codec.binary.Base64;
-
-/**
- * Java class that stores that modules configuration to be used for create BigBlueButton meeting.
- * See the following url for more details
- * https://github.com/mconf/bigbluebutton-api-ruby/blob/master/lib/bigbluebutton_modules.rb
- *
- * @author Yunkai Wang
- */
-public class BBBModule {
- public enum PresentationType {
- url, file, base64;
- }
-
- private LinkedList presentation_urls = new LinkedList();
- private LinkedList presentation_files = new LinkedList();
- private Map presentation_base64s = new HashMap();
-
- public void add_presentation(PresentationType type, String value) {
- add_presentation(type, value, "");
- }
-
- public void add_presentation(PresentationType type, String value, String name) {
- switch (type) {
- case url:
- presentation_urls.add(value);
- return;
- case file:
- presentation_files.add(value);
- return;
- case base64:
- presentation_base64s.put(name, value);
- return;
- }
- }
-
- public String to_xml() throws IOException {
- if (!has_presentation()) return "";
- String xml = "";
- xml += presentations_to_xml();
- xml += "";
- return xml;
- }
-
- private String presentations_to_xml() throws IOException {
- String xml = "";
- for (String url : presentation_urls)
- xml += String.format("", url);
- for (Map.Entry entry : presentation_base64s.entrySet()) {
- xml += String.format("", entry.getKey());
- xml += entry.getValue();
- xml += "";
- }
-
- for (String fileName : presentation_files) {
- File f = new File(fileName);
- xml += String.format("", f.getName());
- FileReader fr = new FileReader(fileName);
- BufferedReader br = new BufferedReader(fr);
- String file = "";
- String line = "";
- while ((line = br.readLine()) != null)
- file += line + "\n";
- br.close();
- byte[] bytes = Base64.encodeBase64(file.getBytes());
- for (byte b : bytes)
- xml += (char)b;
- xml += "";
- }
- xml += "";
- return xml;
- }
-
- private boolean has_presentation() {
- return !(presentation_urls.isEmpty() &&
- presentation_files.isEmpty() &&
- presentation_base64s.isEmpty());
- }
-}
diff --git a/src/BigBlueButton/impl/BaseBBBAPI.java b/src/BigBlueButton/impl/BaseBBBAPI.java
deleted file mode 100644
index 3500a27..0000000
--- a/src/BigBlueButton/impl/BaseBBBAPI.java
+++ /dev/null
@@ -1,684 +0,0 @@
-package BigBlueButton.impl;
-
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.HashMap;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import BigBlueButton.api.BBBException;
-import BigBlueButton.api.BBBMeeting;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-/**
- * Base class for interacting with any BigBlueButton API version.
- * @author Nuno Fernandes
- *
- * Last modified by Yunkai Wang
- */
-public class BaseBBBAPI implements BBBAPI {
- /**
- * BBB server url, including bigbluebutton webapp path. Will default to
- * http://localhost/bigbluebutton if not specified
- */
- protected String bbbUrl = "http://127.0.0.1/bigbluebutton";
- /** BBB security salt */
- protected String bbbSalt = null;
-
- // API Server Path
- protected final static String API_SERVERPATH = "/api/";
-
- // API Calls
- protected final static String APICALL_CREATE = "create";
- protected final static String APICALL_ISMEETINGRUNNING = "isMeetingRunning";
- protected final static String APICALL_GETMEETINGINFO = "getMeetingInfo";
- protected final static String APICALL_GETMEETINGS = "getMeetings";
- protected final static String APICALL_JOIN = "join";
- protected final static String APICALL_END = "end";
- protected final static String APICALL_VERSION = "";
- protected final static String APICALL_getRecordS = "getRecordings";
- protected final static String APICALL_PUBLISHRECORDINGS = "publishRecordings";
- protected final static String APICALL_UPDATERECORDINGS = "updateRecordings";
- protected final static String APICALL_DELETERECORDINGS = "deleteRecordings";
- protected final static String APICALL_GETCONFIGXML = "getDefaultConfigXML";
- protected final static String APICALL_SETCONFIGXML = "setConfigXML";
-
- // API Response Codes
- protected final static String APIRESPONSE_SUCCESS = "SUCCESS";
- protected final static String APIRESPONSE_FAILED = "FAILED";
-
- // API Versions
- public final static String APIVERSION_063 = "0.63";
- public final static String APIVERSION_064 = "0.64";
- public final static String APIVERSION_070 = "0.70";
- public final static String APIVERSION_080 = "0.80";
- public final static String APIVERSION_081 = "0.81";
- public final static String APIVERSION_MINIMUM = APIVERSION_063;
- public final static String APIVERSION_LATEST = APIVERSION_081;
-
- // -----------------------------------------------------------------------
- // --- Initialization related methods ------------------------------------
- // -----------------------------------------------------------------------
- public BaseBBBAPI(String url, String salt) {
- this.bbbUrl = url;
-
- if (bbbUrl.endsWith("/") && bbbUrl.length() > 0) {
- bbbUrl = bbbUrl.substring(0, bbbUrl.length() - 1);
- }
-
- this.bbbSalt = salt;
- }
-
- public String getUrl() {
- return this.bbbUrl;
- }
-
- /*
- public String getSalt() {
- return this.bbbSalt;
- }
- */
-
- private String encode(String msg) throws UnsupportedEncodingException {
- return URLEncoder.encode(msg, getParametersEncoding());
- }
-
- // -----------------------------------------------------------------------
- // --- BBB API implementation methods ------------------------------------
- // -----------------------------------------------------------------------
-
- /* Create BBB meeting */
- public BBBMeeting createMeeting(final String meetingID) throws BBBException {
- return createMeeting(new BBBMeeting(meetingID), null);
- }
-
- public BBBMeeting createMeeting(final BBBMeeting meeting) throws BBBException {
- return createMeeting(meeting, null);
- }
-
- public BBBMeeting createMeeting(final BBBMeeting meeting, final BBBModule module) throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append("meetingID=" + meeting.getMeetingID());
- if (meeting.getName() != null)
- query.append("&name=" + encode(meeting.getName()));
- if (meeting.getAttendeePW() != null)
- query.append("&attendeePW=" + meeting.getAttendeePW());
- if (meeting.getModeratorPW() != null)
- query.append("&moderatorPW=" + meeting.getModeratorPW());
- if (meeting.getWelcome() != null)
- query.append("&welcome=" + encode(meeting.getWelcome()));
- if (meeting.getDialNumber() != null)
- query.append("&dialNumber=" + meeting.getDialNumber());
- if (meeting.getVoiceBridge() != null)
- query.append("&voiceBridge=" + meeting.getVoiceBridge());
- if (meeting.getWebVoice() != null)
- query.append("&webVoice=" + encode(meeting.getWebVoice()));
- if (meeting.getLogoutURL() != null)
- query.append("&logoutURL=" + encode(meeting.getLogoutURL()));
- if (meeting.getRecord() != null)
- query.append("&record=" + Boolean.toString(meeting.getRecord()));
- if (meeting.getDuration() != null)
- query.append("&duration=" + meeting.getDuration().toString());
- if (!meeting.getMeta().isEmpty()) {
- for(Entry entry : meeting.getMeta().entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- query.append("&meta_" + key + "=");
- query.append(encode(value));
- }
- }
- if (meeting.getModeratorOnlyMessage() != null)
- query.append("&moderatorOnlyMessage=" + encode(meeting.getModeratorOnlyMessage()));
- if (meeting.getAutoStartRecording() != null)
- query.append("&autoStartRecording=" + Boolean.toString(meeting.getAutoStartRecording()));
- if (meeting.getAllowStartStopRecording() != null)
- query.append("&allowStartStopRecording=" + Boolean.toString(meeting.getAllowStartStopRecording()));
- if (meeting.getWebcamsOnlyForModerator() != null)
- query.append("&logo=" + Boolean.toString(meeting.getWebcamsOnlyForModerator()));
- if (meeting.getLogo() != null)
- query.append("&logo=" + encode(meeting.getLogo()));
- if (meeting.getCopyright() != null)
- query.append("©right=" + encode(meeting.getCopyright()));
- if (meeting.getMuteOnStart() != null)
- query.append("&muteOnStart=" + Boolean.toString(meeting.getMuteOnStart()));
- query.append(getCheckSumParameterForQuery(APICALL_CREATE, query.toString()));
-
- Map response = doAPICall(APICALL_CREATE, query.toString(),
- module == null ? null : module.to_xml());
-
- // capture important information from returned response
- meeting.setModeratorPW((String)response.get("moderatorPW"));
- meeting.setAttendeePW((String)response.get("attendeePW"));
- meeting.setDialNumber((String)response.get("dialNumber"));
- meeting.setVoiceBridge((String)response.get("voiceBridge"));
- SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
- try {
- meeting.setStartDate(formatter.parse((String)response.get("createDate")));
- } catch (ParseException e) { }
-
- return meeting;
- } catch (BBBException e) {
- throw e;
- } catch (IOException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /* Check if meeting is running */
- public boolean isMeetingRunning(String meetingID)
- throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append("meetingID=" + meetingID);
- query.append(getCheckSumParameterForQuery(APICALL_ISMEETINGRUNNING, query.toString()));
-
- Map response = doAPICall(APICALL_ISMEETINGRUNNING, query.toString());
- return Boolean.parseBoolean((String) response.get("running"));
- } catch (Exception e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /* Get list of all running BBB meetings */
- public Map getMeetings() throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append(getCheckSumParameterForQuery(APICALL_GETMEETINGS, query.toString()));
- Map response = doAPICall(APICALL_GETMEETINGS, query.toString());
-
- return response;
- } catch (Exception e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /* Get BBB meeting information */
- public Map getMeetingInfo(final BBBMeeting meeting) throws BBBException {
- return getMeetingInfo(meeting.getMeetingID(), meeting.getModeratorPW());
- }
-
- public Map getMeetingInfo(String meetingID, String password)
- throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append("meetingID=" + meetingID);
- query.append("&password=" + password);
- query.append(getCheckSumParameterForQuery(APICALL_GETMEETINGINFO, query.toString()));
- Map response = doAPICall(APICALL_GETMEETINGINFO, query.toString());
- return response;
- } catch (BBBException e) {
- throw new BBBException(e.getMessageKey(), e.getMessage(), e);
- }
- }
-
- /* End given BBB meeting */
- public boolean endMeeting(final BBBMeeting meeting) throws BBBException {
- return endMeeting(meeting.getMeetingID(), meeting.getModeratorPW());
- }
-
- public boolean endMeeting(String meetingID, String password) throws BBBException {
- StringBuilder query = new StringBuilder();
- query.append("meetingID=" + meetingID);
- query.append("&password=" + password);
- query.append(getCheckSumParameterForQuery(APICALL_END, query.toString()));
-
- try {
- doAPICall(APICALL_END, query.toString());
- } catch (BBBException e) {
- if(BBBException.MESSAGEKEY_NOTFOUND.equals(e.getMessageKey())) {
- // we can safely ignore this one: the meeting is not running
- return true;
- }else{
- throw e;
- }
- }
-
- return true;
- }
-
- /** Get recordings from BBB server */
- public Map getRecordings() throws BBBException {
- return getRecordings(null, null, null, null);
- }
-
- public Map getRecordings(String meetingIDs) throws BBBException {
- return getRecordings(meetingIDs, null, null, null);
- }
-
- public Map getRecordings(String meetingIDs, String recordIDs) throws BBBException {
- return getRecordings(meetingIDs, recordIDs, null, null);
- }
-
- public Map getRecordings(String meetingIDs, String recordIDs, String states) throws BBBException {
- return getRecordings(meetingIDs, recordIDs, states, null);
- }
-
- public Map getRecordings(String meetingIDs, String recordIDs, String states, Map meta) throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- if (meetingIDs != null)
- query.append("meetingID=" + meetingIDs);
- if (recordIDs != null)
- query.append("recordID=" + recordIDs);
- if (states != null)
- query.append("state=" + states);
- if (meta != null && meta.size() != 0) {
- for(Entry entry : meta.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- query.append("&meta_" + key + "=");
- query.append(encode(value));
- }
- }
- query.append(getCheckSumParameterForQuery(APICALL_getRecordS, query.toString()));
- Map response = doAPICall(APICALL_getRecordS, query.toString());
-
- return response;
- } catch (BBBException e) {
- throw new BBBException(e.getMessageKey(), e.getMessage(), e);
- } catch (IOException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /* Detete a record from BBB server */
- public boolean deteteRecordings(String recordIDs) throws BBBException {
- StringBuilder query = new StringBuilder();
- query.append("recordID=" + recordIDs);
- query.append(getCheckSumParameterForQuery(APICALL_DELETERECORDINGS, query.toString()));
- try {
- Map response = doAPICall(APICALL_DELETERECORDINGS, query.toString());
- return response.get("returncode").toString().equals("SUCCESS") ? true : false;
- } catch (BBBException e) {
- throw e;
- }
- }
-
- /* Publish/Unpublish a recording on BBB server */
- public boolean publishRecordings(String recordIDs, boolean publish) throws BBBException {
- StringBuilder query = new StringBuilder();
- query.append("recordID=" + recordIDs);
- query.append("&publish=" + Boolean.toString(publish));
- query.append(getCheckSumParameterForQuery(APICALL_PUBLISHRECORDINGS, query.toString()));
-
- try {
- Map response = doAPICall(APICALL_PUBLISHRECORDINGS, query.toString());
- return response.get("returncode").toString().equals("SUCCESS") ? true : false;
- } catch (BBBException e) {
- throw e;
- }
- }
-
- /* Update a recording on BBB server */
- public boolean updateRecordings(String recordingIDs) throws BBBException {
- return updateRecordings(recordingIDs, null);
- }
-
- public boolean updateRecordings(String recordingIDs, Map meta) throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append("recordID=" + recordingIDs);
- if (meta != null && meta.size() != 0) {
- for(Entry entry : meta.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- query.append("&meta_" + key + "=");
- query.append(encode(value));
- }
- }
- query.append(getCheckSumParameterForQuery(APICALL_UPDATERECORDINGS, query.toString()));
- Map response = doAPICall(APICALL_UPDATERECORDINGS, query.toString());
- return response.get("returncode").toString().equals("SUCCESS") ? true : false;
- } catch (BBBException e) {
- throw e;
- } catch (IOException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /* Build the join meeting url based on user role */
- public String getJoinMeetingURL(String meetingID, String password, String userDisplayName) {
- return getJoinMeetingURL(meetingID, password, userDisplayName, null);
- }
-
- public String getJoinMeetingURL(String meetingID, String password, String userDisplayName, String userId) {
- StringBuilder url = null;
- try {
- StringBuilder joinQuery = new StringBuilder();
- joinQuery.append("meetingID=" + meetingID);
- if (userId != null)
- joinQuery.append("&userID=" + encode(userId));
-
- joinQuery.append("&fullName=");
- userDisplayName = (userDisplayName == null) ? "user" : userDisplayName;
- try {
- joinQuery.append(encode(userDisplayName));
- } catch (UnsupportedEncodingException e) {
- joinQuery.append(userDisplayName);
- }
- joinQuery.append("&password=" + password);
- joinQuery.append(getCheckSumParameterForQuery(APICALL_JOIN, joinQuery.toString()));
-
- url = new StringBuilder(bbbUrl);
- if (url.toString().endsWith("/api")) {
- url.append("/");
- } else {
- url.append(API_SERVERPATH);
- }
- url.append(APICALL_JOIN + "?" + joinQuery);
- } catch (UnsupportedEncodingException e) { }
- return url.toString();
- }
-
- /* Download default config xml file from the server and save the file to given file location */
- public boolean getDefaultConfigXML(String filePath) throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append(getCheckSumParameterForQuery(APICALL_GETCONFIGXML, query.toString()));
- Map response = doAPICall(APICALL_GETCONFIGXML, query.toString());
-
- File file = new File(filePath);
- if (file.exists() && !file.canWrite()) {
- throw new IOException("Failed to edit " + filePath);
- } else if (!file.exists()) {
- if (!file.createNewFile())
- throw new IOException("Failed to create " + filePath);
- }
-
- FileOutputStream output = new FileOutputStream(file);
- output.write(((String)response.get("xml")).getBytes());
- output.close();
- return true;
- } catch (BBBException e) {
- throw e;
- } catch (IOException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /* set the config.xml file for the given meeting */
- public boolean setConfigXML(String meetingID, String filePath) throws BBBException {
- try {
- StringBuilder query = new StringBuilder();
- query.append("meetingID=" + meetingID);
- query.append(getCheckSumParameterForQuery(APICALL_SETCONFIGXML, query.toString()));
-
- File file = new File(filePath);
- if (!file.exists() || !file.canRead()) {
- throw new IOException("Failed to read " + filePath);
- }
-
- FileInputStream input = new FileInputStream(file);
- byte[] b = input.readAllBytes();
- input.close();
- String xml = "";
- for (byte a : b)
- xml += (char)a;
- query.append("&configXML=" + encode(xml));
-
- Map response = doAPICall(APICALL_SETCONFIGXML, query.toString());
- return response.get("returncode").toString().equals("SUCCESS") ? true : false;
- } catch (BBBException e) {
- throw e;
- } catch (IOException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INTERNALERROR, e.getMessage(), e);
- }
- }
-
- /** Get the BBB API version running on BBB server */
- public final String getAPIVersion() {
- String _version = null;
- try {
- Map response = doAPICall(APICALL_VERSION, null);
- _version = (String) response.get("version");
- _version = _version != null ? _version.trim() : null;
- if (_version == null || Float.valueOf(_version.substring(0, 3)) < 0.0) {
- _version = null;
- }
- _version = _version.trim();
- } catch (BBBException e) {
- if (BBBException.MESSAGEKEY_NOACTION.equals(e.getMessageKey())) {
- // we are clearly connecting to BBB < 0.70 => assuming minimum
- // version (0.63)
- _version = APIVERSION_MINIMUM;
- } else {
- // something went wrong => warn user
- _version = null;
- }
- } catch (Exception e) {
- // something went wrong => warn user
- _version = null;
- }
- return _version;
- }
-
- // -----------------------------------------------------------------------
- // --- BBB API utility methods -------------------------------------------
- // -----------------------------------------------------------------------
- /** Compute the query string checksum based on the security salt */
- protected String getCheckSumParameterForQuery(String apiCall,
- String queryString) {
- if (bbbSalt != null)
- return "&checksum=" + DigestUtils.shaHex(apiCall + queryString + bbbSalt);
- else
- return "";
- }
-
- /** Encoding used when encoding url parameters */
- protected String getParametersEncoding() {
- return "UTF-8";
- }
-
-
- /* Make an API call */
- protected Map doAPICall(String apiCall, String query) throws BBBException {
- return doAPICall(apiCall, query, null);
- }
-
- protected Map doAPICall(String apiCall, String query, String data) throws BBBException {
- StringBuilder urlStr = new StringBuilder(bbbUrl);
- if (urlStr.toString().endsWith("/api")){
- urlStr.append("/");
- } else {
- urlStr.append(API_SERVERPATH);
- }
- urlStr.append(apiCall);
- if (query != null) {
- urlStr.append("?");
- urlStr.append(query);
- }
-
- try {
- // open connection
- URL url = new URL(urlStr.toString());
- HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
- httpConnection.setUseCaches(false);
- httpConnection.setDoOutput(true);
- if(data != null){
- httpConnection.setRequestMethod("POST");
- httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- httpConnection.setRequestProperty("Content-Length", "" + data.length());
- httpConnection.setRequestProperty("Content-Language", "en-US");
- httpConnection.setDoInput(true);
-
- DataOutputStream wr = new DataOutputStream( httpConnection.getOutputStream() );
- wr.writeBytes (data);
- wr.flush();
- wr.close();
- } else {
- httpConnection.setRequestMethod("GET");
- }
- httpConnection.connect();
-
- int responseCode = httpConnection.getResponseCode();
- if (responseCode == HttpURLConnection.HTTP_OK) {
- // read response
- InputStreamReader isr = null;
- BufferedReader reader = null;
- StringBuilder xml = new StringBuilder();
- try {
- isr = new InputStreamReader(httpConnection.getInputStream(), "UTF-8");
- reader = new BufferedReader(isr);
- String line = reader.readLine();
- while (line != null) {
- if( !line.startsWith(""))
- xml.append(line.trim());
- line = reader.readLine();
- }
- } finally {
- if (reader != null)
- reader.close();
- if (isr != null)
- isr.close();
- }
- httpConnection.disconnect();
-
- // parse response
- //Patch to fix the NaN error
- String stringXml = xml.toString();
- stringXml = stringXml.replaceAll(">.\\s+?<", "><");
-
- if (apiCall.equals(APICALL_GETCONFIGXML)) {
- Map map = new HashMap();
- map.put("xml", stringXml);
- return map;
- }
-
- Document dom = null;
-
- // Initialize XML libraries
- DocumentBuilderFactory docBuilderFactory;
- DocumentBuilder docBuilder;
- docBuilderFactory = DocumentBuilderFactory.newInstance();
- try {
- docBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
- docBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
-
- docBuilder = docBuilderFactory.newDocumentBuilder();
- dom = docBuilder.parse(new InputSource( new StringReader(stringXml)));
- } catch (ParserConfigurationException e) { }
- Map response = getNodesAsMap(dom, "response");
-
- String returnCode = (String) response.get("returncode");
- if (APIRESPONSE_FAILED.equals(returnCode)) {
- throw new BBBException((String) response.get("messageKey"), (String) response.get("message"));
- }
-
- return response;
- } else {
- throw new BBBException(BBBException.MESSAGEKEY_HTTPERROR, "BBB server responded with HTTP status code " + responseCode);
- }
-
- } catch(BBBException e) {
- throw new BBBException( e.getMessageKey(), e.getMessage(), e);
- } catch(IOException e) {
- throw new BBBException(BBBException.MESSAGEKEY_UNREACHABLE, e.getMessage(), e);
- } catch(SAXException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INVALIDRESPONSE, e.getMessage(), e);
- } catch(IllegalArgumentException e) {
- throw new BBBException(BBBException.MESSAGEKEY_INVALIDRESPONSE, e.getMessage(), e);
- } catch(Exception e) {
- throw new BBBException(BBBException.MESSAGEKEY_UNREACHABLE, e.getMessage(), e);
- }
- }
-
-
- // -----------------------------------------------------------------------
- // --- BBB Other utility methods -----------------------------------------
- // -----------------------------------------------------------------------
- /** Get all nodes under the specified element tag name as a Java map */
- protected Map getNodesAsMap(Document dom, String elementTagName) {
- Node firstNode = dom.getElementsByTagName(elementTagName).item(0);
- return processNode(firstNode);
- }
-
- protected Map processNode(Node _node) {
- Map map = new HashMap();
- NodeList responseNodes = _node.getChildNodes();
- int images = 1; //counter for images (i.e image1, image2, image3)
- for (int i = 0; i < responseNodes.getLength(); i++) {
- Node node = responseNodes.item(i);
- String nodeName = node.getNodeName().trim();
- if (node.getChildNodes().getLength() == 1
- && ( node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.TEXT_NODE || node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) ) {
- String nodeValue = node.getTextContent();
- if (nodeName == "image" && node.getAttributes() != null){
- Map imageMap = new HashMap();
- Node heightAttr = node.getAttributes().getNamedItem("height");
- Node widthAttr = node.getAttributes().getNamedItem("width");
- Node altAttr = node.getAttributes().getNamedItem("alt");
-
- imageMap.put("height", heightAttr.getNodeValue());
- imageMap.put("width", widthAttr.getNodeValue());
- imageMap.put("title", altAttr.getNodeValue());
- imageMap.put("url", nodeValue);
- map.put(nodeName + images, imageMap);
- images++;
- } else {
- map.put(nodeName, nodeValue != null ? nodeValue.trim() : null);
- }
- } else if (node.getChildNodes().getLength() == 0
- && node.getNodeType() != org.w3c.dom.Node.TEXT_NODE
- && node.getNodeType() != org.w3c.dom.Node.CDATA_SECTION_NODE) {
- map.put(nodeName, "");
- } else if (node.getChildNodes().getLength() >= 1) {
- boolean isList = false;
- for (int c = 0; c < node.getChildNodes().getLength(); ++c) {
- try {
- Node n = node.getChildNodes().item(c);
- if (n.getChildNodes().item(0).getNodeType() != org.w3c.dom.Node.TEXT_NODE
- && n.getChildNodes().item(0).getNodeType() != org.w3c.dom.Node.CDATA_SECTION_NODE) {
- isList = true;
- break;
- }
- } catch (Exception e) {
- continue;
- }
- }
- List