Normalize all the line endings
Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/8e63647c Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/8e63647c Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/8e63647c Branch: refs/heads/master Commit: 8e63647cd04854282483beb1cc5d03163d3b86c2 Parents: eacff5b Author: Maxim Solodovnik <[email protected]> Authored: Thu May 18 12:38:51 2017 +0700 Committer: Maxim Solodovnik <[email protected]> Committed: Thu May 18 12:38:51 2017 +0700 ---------------------------------------------------------------------- NOTICE | 28 +- README | 248 ++--- .../record/listener/async/BaseStreamWriter.java | 400 +++---- .../data/record/listener/async/CachedEvent.java | 152 +-- .../listener/async/StreamAudioWriter.java | 456 ++++---- .../listener/async/StreamVideoWriter.java | 196 ++-- .../openmeetings/core/mail/SMSHandler.java | 236 ++-- .../core/session/SessionManager.java | 730 ++++++------- openmeetings-core/src/site/site.xml | 80 +- .../test/rtmp/LoadTestRtmpClient.java | 344 +++--- .../openmeetings/test/rtmp/SimulateLoad.java | 184 ++-- .../openmeetings/db/dao/IDataProviderDao.java | 188 ++-- .../db/dao/basic/MailMessageDao.java | 270 ++--- .../openmeetings/db/dao/label/LabelDao.java | 642 +++++------ .../apache/openmeetings/db/dao/room/SipDao.java | 382 +++---- .../db/dao/server/ISessionManager.java | 412 +++---- .../openmeetings/db/dao/server/ServerDao.java | 444 ++++---- .../openmeetings/db/dao/user/GroupDao.java | 292 ++--- .../openmeetings/db/dao/user/GroupUserDao.java | 248 ++--- .../db/entity/basic/MailMessage.java | 398 +++---- .../openmeetings/db/entity/server/Server.java | 608 +++++------ .../openmeetings/db/util/FormatHelper.java | 162 +-- openmeetings-db/src/site/site.xml | 80 +- openmeetings-flash/src/main/flex/main.mxml | 642 +++++------ .../flex/org/apache/openmeetings/OmVideo.as | 540 +++++----- .../swf10/networkTesting/networktesting.lzx | 178 +-- .../swf10/networkTesting/rtmpConnection.lzx | 734 ++++++------- .../networkTesting/tests/BaseURLLoadTest.lzx | 292 ++--- .../networkTesting/tests/DownloadSpeedTest.lzx | 100 +- .../swf10/networkTesting/tests/JitterTest.lzx | 114 +- .../swf10/networkTesting/tests/NetworkTest.lzx | 256 ++--- .../swf10/networkTesting/tests/PingTest.lzx | 86 +- .../tests/PortAvailabilityTest.lzx | 180 ++-- .../networkTesting/tests/UploadSpeedTest.lzx | 248 ++--- .../main/swf10/networkTesting/tests/library.lzx | 74 +- .../src/main/swf10/networkTesting/testsView.lzx | 210 ++-- openmeetings-flash/src/site/site.xml | 78 +- .../backup/AppointmentConverter.java | 108 +- .../AppointmentReminderTypeConverter.java | 78 +- .../openmeetings/backup/DateConverter.java | 80 +- .../openmeetings/backup/GroupConverter.java | 108 +- .../openmeetings/backup/InlineConverter.java | 58 +- .../openmeetings/backup/IntegerTransform.java | 68 +- .../openmeetings/backup/LongTransform.java | 66 +- .../backup/OmCalendarConverter.java | 110 +- .../apache/openmeetings/backup/OmConverter.java | 112 +- .../openmeetings/backup/PollTypeConverter.java | 74 +- .../backup/RecordingStatusConverter.java | 94 +- .../openmeetings/backup/RoomConverter.java | 108 +- .../openmeetings/backup/RoomTypeConverter.java | 74 +- .../backup/SalutationConverter.java | 70 +- .../openmeetings/backup/UserConverter.java | 108 +- .../cli/ConnectionPropertiesPatcher.java | 378 +++---- .../org/apache/openmeetings/cli/Db2Patcher.java | 56 +- .../apache/openmeetings/cli/DerbyPatcher.java | 66 +- .../apache/openmeetings/cli/MssqlPatcher.java | 56 +- .../apache/openmeetings/cli/MysqlPatcher.java | 58 +- .../apache/openmeetings/cli/OraclePatcher.java | 64 +- .../openmeetings/cli/PostgresPatcher.java | 56 +- .../installation/InstallationConfig.java | 198 ++-- openmeetings-install/src/site/site.xml | 78 +- .../openmeetings/screenshare/CaptureScreen.java | 474 ++++---- .../screenshare/IScreenEncoder.java | 66 +- .../screenshare/RTMPClientPublish.java | 204 ++-- .../screenshare/ScreenV1Encoder.java | 404 +++---- .../screenshare/gui/MouseListenerable.java | 62 +- .../screenshare/gui/NumberSpinner.java | 70 +- .../src/main/resources/logback.xsd | 218 ++-- openmeetings-screenshare/src/site/site.xml | 78 +- .../src/main/assembly/jrebel/red5-debug.bat | 38 +- .../src/main/assembly/scripts/admin.bat | 42 +- openmeetings-server/src/site/site.xml | 280 ++--- .../src/site/stylesheets/errortable.xsl | 134 +-- .../src/site/xdoc/ApacheDerbyConfig.xml | 114 +- .../src/site/xdoc/BitrixPlugin.xml | 96 +- .../src/site/xdoc/BuildInstructions.xml | 208 ++-- .../src/site/xdoc/BuildInstructions_3.0.x.xml | 608 +++++------ .../src/site/xdoc/CalendarAndTimezone.xml | 134 +-- .../src/site/xdoc/CallForLogo.xml | 486 ++++----- .../src/site/xdoc/Clustering.xml | 278 ++--- .../src/site/xdoc/CommandLineAdmin.xml | 200 ++-- .../site/xdoc/ConferenceRoomLayoutOptions.xml | 174 +-- .../src/site/xdoc/ConfluencePlugin.xml | 98 +- .../src/site/xdoc/CustomCryptMechanism.xml | 206 ++-- .../src/site/xdoc/CustomRoomTypeHowTo.xml | 206 ++-- openmeetings-server/src/site/xdoc/Dashboard.xml | 138 +-- .../src/site/xdoc/DrupalPlugin.xml | 150 +-- .../src/site/xdoc/EditTemplates.xml | 128 +-- .../src/site/xdoc/GeneralConfiguration.xml | 626 +++++------ .../src/site/xdoc/GetVersionInfo.xml | 144 +-- openmeetings-server/src/site/xdoc/HotKeys.xml | 106 +- .../src/site/xdoc/IBMDB2Config.xml | 146 +-- .../src/site/xdoc/Internationalisation.xml | 96 +- .../src/site/xdoc/JUnitTesting.xml | 170 +-- .../src/site/xdoc/JVMPerformanceTuning.xml | 132 +-- .../src/site/xdoc/JiraPlugin.xml | 102 +- .../src/site/xdoc/JoomlaPlugin.xml | 118 +- .../src/site/xdoc/LanguageEditor.xml | 116 +- .../src/site/xdoc/LdapAndADS.xml | 190 ++-- .../src/site/xdoc/MSSQLConfig.xml | 152 +-- .../src/site/xdoc/ManualTesting.xml | 1002 ++++++++--------- .../src/site/xdoc/MoodlePlugin.xml | 152 +-- .../src/site/xdoc/MySQLConfig.xml | 152 +-- .../src/site/xdoc/Navigation.xml | 86 +- .../src/site/xdoc/OpenOfficeConverter.xml | 108 +- .../src/site/xdoc/OracleConfig.xml | 122 +-- .../src/site/xdoc/PortSettings.xml | 172 +-- .../src/site/xdoc/PostgresConfig.xml | 144 +-- .../src/site/xdoc/RTMPSAndHTTPS.xml | 434 ++++---- .../src/site/xdoc/RecommendedHardwareList.xml | 118 +- .../src/site/xdoc/RedminePlugin.xml | 68 +- .../src/site/xdoc/ReleaseGuide.xml | 628 +++++------ .../src/site/xdoc/RestAPISample.xml | 278 ++--- .../src/site/xdoc/RestrictedAccess.xml | 144 +-- .../src/site/xdoc/SakaiPlugin.xml | 220 ++-- .../src/site/xdoc/SugarCRMPlugin.xml | 146 +-- .../src/site/xdoc/TimeZoneHandling.xml | 78 +- openmeetings-server/src/site/xdoc/Upgrade.xml | 192 ++-- .../src/site/xdoc/WebappNamePath.xml | 302 +++--- .../src/site/xdoc/WebcamResolutions.xml | 118 +- .../src/site/xdoc/WebsiteGuide.xml | 160 +-- .../src/site/xdoc/commercial-support.xml | 112 +- .../src/site/xdoc/installation.xml | 530 ++++----- .../src/site/xdoc/red5sip-integration_2.0.xml | 356 +++--- .../src/site/xdoc/themes-and-branding.xml | 122 +-- .../src/site/xdoc/voip-sip-integration.xml | 144 +-- .../service/quartz/scheduler/CleanupJob.java | 358 +++--- openmeetings-service/src/site/site.xml | 80 +- .../openmeetings/util/ConnectionProperties.java | 172 +-- .../org/apache/openmeetings/util/DaoHelper.java | 214 ++-- .../apache/openmeetings/util/OmFileHelper.java | 632 +++++------ .../org/apache/openmeetings/util/Version.java | 196 ++-- .../apache/openmeetings/util/mail/MailUtil.java | 68 +- .../util/process/ProcessHelper.java | 232 ++-- openmeetings-util/src/site/site.xml | 80 +- .../openmeetings/web/admin/AdminBaseForm.java | 362 +++---- .../web/admin/SearchableDataView.java | 90 +- .../web/admin/backup/BackupPanel.java | 518 ++++----- .../web/admin/configurations/ConfigForm.java | 286 ++--- .../web/admin/configurations/ConfigsPanel.java | 188 ++-- .../web/admin/groups/GroupForm.java | 500 ++++----- .../web/admin/groups/GroupUsersPanel.html | 90 +- .../web/admin/groups/GroupUsersPanel.java | 318 +++--- .../web/admin/groups/GroupsPanel.java | 198 ++-- .../web/admin/labels/AddLanguageDialog.java | 230 ++-- .../web/admin/labels/LabelsForm.java | 224 ++-- .../openmeetings/web/admin/labels/LangForm.java | 206 ++-- .../openmeetings/web/admin/ldaps/LdapForm.java | 260 ++--- .../web/admin/ldaps/LdapsPanel.java | 186 ++-- .../openmeetings/web/admin/rooms/RoomForm.java | 824 +++++++------- .../web/admin/rooms/RoomsPanel.java | 182 ++-- .../web/admin/servers/ServerForm.java | 280 ++--- .../web/admin/servers/ServersPanel.java | 190 ++-- .../openmeetings/web/admin/users/UserForm.java | 628 +++++------ .../web/app/LabelResourceLoader.java | 130 +-- .../web/common/ConfirmableAjaxBorder.java | 354 +++--- .../openmeetings/web/common/HeaderPanel.html | 52 +- .../openmeetings/web/common/HeaderPanel.java | 64 +- .../web/common/OmPagingNavigator.html | 54 +- .../web/common/OmPagingNavigator.java | 64 +- .../openmeetings/web/common/menu/MenuPanel.html | 50 +- .../openmeetings/web/common/menu/MenuPanel.java | 138 +-- .../web/data/DataViewContainer.java | 106 +- .../openmeetings/web/data/OmOrderByBorder.java | 90 +- .../web/data/SearchableDataProvider.java | 184 ++-- .../openmeetings/web/pages/ActivatePage.java | 102 +- .../openmeetings/web/pages/NotInitedPage.html | 64 +- .../openmeetings/web/pages/NotInitedPage.java | 80 +- .../openmeetings/web/pages/ResetPage.html | 50 +- .../openmeetings/web/pages/ResetPage.java | 88 +- .../web/pages/auth/KickMessageDialog.html | 56 +- .../web/pages/auth/KickMessageDialog.java | 116 +- .../web/pages/auth/ResetPasswordDialog.html | 84 +- .../web/pages/auth/ResetPasswordDialog.java | 314 +++--- .../web/room/jquery.dialogextend.js | 658 +++++------ .../web/room/jquery.dialogextend.min.js | 4 +- .../openmeetings/web/user/AboutDialog.html | 84 +- .../openmeetings/web/user/AboutDialog.java | 114 +- .../openmeetings/web/user/UserInfoDialog.html | 54 +- .../openmeetings/web/user/UserInfoDialog.java | 166 +-- .../web/user/calendar/AppointmentDialog.html | 242 ++--- .../web/user/calendar/AppointmentDialog.java | 1020 +++++++++--------- .../web/user/calendar/AppointmentModel.java | 102 +- .../web/user/dashboard/MyRoomsWidget.java | 98 +- .../user/dashboard/MyRoomsWidgetDescriptor.java | 102 +- .../web/user/dashboard/MyRoomsWidgetView.html | 50 +- .../web/user/dashboard/MyRoomsWidgetView.java | 72 +- .../web/user/dashboard/OmDashboardPanel.html | 50 +- .../web/user/dashboard/OmDashboardPanel.java | 72 +- .../web/user/dashboard/RecentRoomsWidget.java | 98 +- .../dashboard/RecentRoomsWidgetDescriptor.java | 102 +- .../user/dashboard/RecentRoomsWidgetView.html | 50 +- .../user/dashboard/RecentRoomsWidgetView.java | 76 +- .../web/user/dashboard/RssWidget.java | 98 +- .../web/user/dashboard/RssWidgetDescriptor.java | 102 +- .../web/user/dashboard/RssWidgetView.java | 194 ++-- .../web/user/dashboard/StartWidget.java | 96 +- .../user/dashboard/StartWidgetDescriptor.java | 102 +- .../web/user/dashboard/StartWidgetView.html | 76 +- .../web/user/dashboard/StartWidgetView.java | 138 +-- .../web/user/dashboard/WelcomeWidget.java | 96 +- .../user/dashboard/WelcomeWidgetDescriptor.java | 102 +- .../web/user/dashboard/WelcomeWidgetView.html | 86 +- .../web/user/dashboard/WelcomeWidgetView.java | 162 +-- .../web/user/dashboard/admin/AdminWidget.java | 98 +- .../dashboard/admin/AdminWidgetDescriptor.java | 102 +- .../user/dashboard/admin/AdminWidgetView.html | 58 +- .../user/dashboard/admin/AdminWidgetView.java | 108 +- .../web/user/profile/UserProfilePanel.html | 174 +-- .../web/user/profile/UserProfilePanel.java | 146 +-- .../web/user/profile/UserSearchPanel.html | 136 +-- .../web/user/profile/UserSearchPanel.java | 308 +++--- .../openmeetings/web/user/rooms/RoomsPanel.html | 124 +-- .../openmeetings/web/user/rooms/RoomsPanel.java | 274 ++--- .../web/user/rooms/RoomsSelectorPanel.html | 54 +- .../web/user/rooms/RoomsSelectorPanel.java | 112 +- .../web/user/rooms/RoomsTabbedPanel.html | 60 +- .../web/user/rooms/RoomsTabbedPanel.java | 140 +-- .../src/main/webapp/conf/om_ldap.cfg | 218 ++-- .../src/main/webapp/languages/errorvalues.xsd | 82 +- openmeetings-web/src/site/site.xml | 78 +- .../openmeetings/test/AbstractWicketTester.java | 154 +-- .../test/backup/TestOldBackups.java | 256 ++--- .../openmeetings/test/user/TestUserContact.java | 210 ++-- .../openmeetings/test/user/TestUserCount.java | 116 +- .../webservice/ServerWebService.java | 360 +++---- .../cluster/SlaveHTTPConnectionManager.java | 198 ++-- openmeetings-webservice/src/site/site.xml | 80 +- src/site/site.xml | 154 +-- 229 files changed, 22508 insertions(+), 22508 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/NOTICE ---------------------------------------------------------------------- diff --git a/NOTICE b/NOTICE index 6685a3f..eddf910 100644 --- a/NOTICE +++ b/NOTICE @@ -1,14 +1,14 @@ -Apache OpenMeetings -Copyright 2011-2017 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - -This product includes icons from FamFamFam Icon Set Silk. -http://www.famfamfam.com/lab/icons/silk/ - -This product includes icons from Yusuke Kamiyamane. -http://p.yusukekamiyamane.com/ - -This product includes free icons from FatCow. -http://www.fatcow.com/free-icons +Apache OpenMeetings +Copyright 2011-2017 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes icons from FamFamFam Icon Set Silk. +http://www.famfamfam.com/lab/icons/silk/ + +This product includes icons from Yusuke Kamiyamane. +http://p.yusukekamiyamane.com/ + +This product includes free icons from FatCow. +http://www.fatcow.com/free-icons http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/README ---------------------------------------------------------------------- diff --git a/README b/README index 6747d28..fb4c599 100644 --- a/README +++ b/README @@ -1,124 +1,124 @@ -Apache OpenMeetings - README -Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0 --------------------------------------------------------------------------------- - -About -===== -Apache OpenMeetings provides video conferencing, instant messaging, white board, -collaborative document editing and other groupware tools using API functions of -the Red5 Streaming Server for Remoting and Streaming. - -Release Notes 3.2.1 -============= -see CHANGELOG file for detailed log - -Service release 1 for 3.2.0, provides following improvements: - -Room -* Video is more stable -* Office files download is fixed -* Multi-upload is added -* External video works as expected -* WB drawing on slides works as expected - -Chat -* chat is made resizable -* multiple issues in chat are fixed -* typing indicator is added - -Calendar -* date/time validator is improved -* whole group can be invited by admin to event - -Other fixes and improvements, 49 issues were fixed - - -============= -_Integration with Asterisk_ -SIP/VOIP integration with Asterisk was refactored. -Confbridge application is now used instead of Meetme for the conferences. -Sound quality and SIP transport stability was significantly improved. -Basic support for video is added (is unstable and in beta version stage now). -See also: http://openmeetings.apache.org/red5sip-integration_2.1.html - -_Improving the sound and video quality_ -All the audio/video related components now use SWF11 for broadcasting and -receiving audio and video signals. -Echo cancellation can be enabled in the config. -H264 video codec is now used instead of H263 to enable SIP video support. - -_Private and moderated chat_ -Ability to send private chat messages in the room is added as well as the chat -moderation funmctionality. - -_SMS sending module_ -Possibility to send SMS message as a meeting reminder is added. -See also: https://cwiki.apache.org/confluence/display/OPENMEETINGS/SMS+Sending+Module - -_Network testing tool/script_ -Network testing tool is implemented and its link is added to the login page. -See also: https://cwiki.apache.org/confluence/display/OPENMEETINGS/Connection+testing+tool - -_Improvements in the mail sending process_ -Now e-mails are re-send again in case of unsuccessfull result at the first -attempt or OpenMeetings re-start before the sending. -SMTP setting updates now takes effect just after they saving whereas previously -they started to work after the OpenMeetings re-start only. - -_Calendar_ -Messages about the meeting updates are sent only when substantial changes were made. -Multiple external attendees can be added as one operation, it's now possible to -specify user name for external guests (user will appear with this name in the user -list in the room). - -_Room Interface_ -Possibility to get invitation link without sending an e-mail was added. -Confirmation dialog for exclusive audio no longer appears. -Hot key is added to be able to "rearrange" video windows in the room. -Volume slider on the video pod toolbar was added. - -_Recordings and screen sharing improvements_ -Some improvements for the screen sharing and recordings quality and stability -were made. - -_Cluster capabilities_ -In the beta stage: OpenMeetings can be configured in the cluster environment and -is ready for the testing, but development has not been fnished yet. -See also: http://openmeetings.apache.org/Clustering.html, -https://cwiki.apache.org/confluence/display/OPENMEETINGS/Cluster+Master-Slave+overview - -_Admin/Calendar HTML5 UI_ -Additional HTML5 Wicket based UI (fully customizable with CSS) is added for -static screens as a proof of the concept. - -Getting Started -=============== -Please visit the project website for the latest information: - http://openmeetings.apache.org/ - -Documentation for Installation and Upgrade: - http://openmeetings.apache.org/installation.html - http://openmeetings.apache.org/Upgrade.html - -Along with the developer mailing list archive: - http://openmeetings.apache.org/mail-lists.html - - -System Requirements -=================== -You need a platform that supports Sun Java SE 6. - - -Building and running -==================== -To build from source code: - - - Requirements: - Sources compilation require Sun Java SE 8. - The project is built with Apache Maven 3.3.9 or later. - - - To build the OpenMeetings project run ant in the root directory: - ant - -For a detailed documentation on how to build from source and options see: - http://openmeetings.apache.org/BuildInstructions.html +Apache OpenMeetings - README +Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0 +-------------------------------------------------------------------------------- + +About +===== +Apache OpenMeetings provides video conferencing, instant messaging, white board, +collaborative document editing and other groupware tools using API functions of +the Red5 Streaming Server for Remoting and Streaming. + +Release Notes 3.2.1 +============= +see CHANGELOG file for detailed log + +Service release 1 for 3.2.0, provides following improvements: + +Room +* Video is more stable +* Office files download is fixed +* Multi-upload is added +* External video works as expected +* WB drawing on slides works as expected + +Chat +* chat is made resizable +* multiple issues in chat are fixed +* typing indicator is added + +Calendar +* date/time validator is improved +* whole group can be invited by admin to event + +Other fixes and improvements, 49 issues were fixed + + +============= +_Integration with Asterisk_ +SIP/VOIP integration with Asterisk was refactored. +Confbridge application is now used instead of Meetme for the conferences. +Sound quality and SIP transport stability was significantly improved. +Basic support for video is added (is unstable and in beta version stage now). +See also: http://openmeetings.apache.org/red5sip-integration_2.1.html + +_Improving the sound and video quality_ +All the audio/video related components now use SWF11 for broadcasting and +receiving audio and video signals. +Echo cancellation can be enabled in the config. +H264 video codec is now used instead of H263 to enable SIP video support. + +_Private and moderated chat_ +Ability to send private chat messages in the room is added as well as the chat +moderation funmctionality. + +_SMS sending module_ +Possibility to send SMS message as a meeting reminder is added. +See also: https://cwiki.apache.org/confluence/display/OPENMEETINGS/SMS+Sending+Module + +_Network testing tool/script_ +Network testing tool is implemented and its link is added to the login page. +See also: https://cwiki.apache.org/confluence/display/OPENMEETINGS/Connection+testing+tool + +_Improvements in the mail sending process_ +Now e-mails are re-send again in case of unsuccessfull result at the first +attempt or OpenMeetings re-start before the sending. +SMTP setting updates now takes effect just after they saving whereas previously +they started to work after the OpenMeetings re-start only. + +_Calendar_ +Messages about the meeting updates are sent only when substantial changes were made. +Multiple external attendees can be added as one operation, it's now possible to +specify user name for external guests (user will appear with this name in the user +list in the room). + +_Room Interface_ +Possibility to get invitation link without sending an e-mail was added. +Confirmation dialog for exclusive audio no longer appears. +Hot key is added to be able to "rearrange" video windows in the room. +Volume slider on the video pod toolbar was added. + +_Recordings and screen sharing improvements_ +Some improvements for the screen sharing and recordings quality and stability +were made. + +_Cluster capabilities_ +In the beta stage: OpenMeetings can be configured in the cluster environment and +is ready for the testing, but development has not been fnished yet. +See also: http://openmeetings.apache.org/Clustering.html, +https://cwiki.apache.org/confluence/display/OPENMEETINGS/Cluster+Master-Slave+overview + +_Admin/Calendar HTML5 UI_ +Additional HTML5 Wicket based UI (fully customizable with CSS) is added for +static screens as a proof of the concept. + +Getting Started +=============== +Please visit the project website for the latest information: + http://openmeetings.apache.org/ + +Documentation for Installation and Upgrade: + http://openmeetings.apache.org/installation.html + http://openmeetings.apache.org/Upgrade.html + +Along with the developer mailing list archive: + http://openmeetings.apache.org/mail-lists.html + + +System Requirements +=================== +You need a platform that supports Sun Java SE 6. + + +Building and running +==================== +To build from source code: + + - Requirements: + Sources compilation require Sun Java SE 8. + The project is built with Apache Maven 3.3.9 or later. + + - To build the OpenMeetings project run ant in the root directory: + ant + +For a detailed documentation on how to build from source and options see: + http://openmeetings.apache.org/BuildInstructions.html http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/BaseStreamWriter.java ---------------------------------------------------------------------- diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/BaseStreamWriter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/BaseStreamWriter.java index de93393..1520204 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/BaseStreamWriter.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/BaseStreamWriter.java @@ -1,200 +1,200 @@ -/* - * 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.core.data.record.listener.async; - -import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV; -import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; - -import java.io.File; -import java.io.IOException; -import java.util.Date; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - -import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao; -import org.apache.openmeetings.db.entity.record.RecordingMetaData; -import org.apache.openmeetings.db.entity.record.RecordingMetaData.Status; -import org.apache.openmeetings.util.OmFileHelper; -import org.red5.io.IStreamableFile; -import org.red5.io.ITagWriter; -import org.red5.logging.Red5LoggerFactory; -import org.red5.server.api.scope.IScope; -import org.red5.server.api.service.IStreamableFileService; -import org.red5.server.api.stream.IStreamableFileFactory; -import org.red5.server.stream.StreamableFileFactory; -import org.red5.server.util.ScopeUtils; -import org.slf4j.Logger; - -public abstract class BaseStreamWriter implements Runnable { - private static final Logger log = Red5LoggerFactory.getLogger(BaseStreamWriter.class, webAppRootKey); - private final static int MINUTE_MULTIPLIER = 60 * 1000; - public final static int TIME_TO_WAIT_FOR_FRAME = 15 * MINUTE_MULTIPLIER; - protected int startTimeStamp = -1; - protected long initialDelta = 0; - - // thread is running - private boolean running = false; - // thread is stopped - private boolean stopping = false; - // thread will be stopped as soon as the queue is empty - private boolean dostopping = false; - - protected ITagWriter writer = null; - - protected Long metaDataId = null; - - protected Date startedSessionTimeDate = null; - - protected File file; - - protected IScope scope; - - protected boolean isScreenData = false; - - protected String streamName = ""; - protected final RecordingMetaDataDao metaDataDao; - private final BlockingQueue<CachedEvent> queue = new LinkedBlockingQueue<>(); - - public BaseStreamWriter(String streamName, IScope scope, Long metaDataId, boolean isScreenData, RecordingMetaDataDao metaDataDao) { - startedSessionTimeDate = new Date(); - this.isScreenData = isScreenData; - this.streamName = streamName; - this.metaDataId = metaDataId; - this.metaDataDao = metaDataDao; - this.scope = scope; - try { - init(); - } catch (IOException ex) { - log.error("##REC:: [BaseStreamWriter] Could not init Thread", ex); - } - RecordingMetaData metaData = metaDataDao.get(metaDataId); - metaData.setStreamStatus(Status.STARTED); - metaDataDao.update(metaData); - - open(); - } - - /** - * Initialization - * - * @throws IOException - * I/O exception - */ - private void init() throws IOException { - file = new File(OmFileHelper.getStreamsSubDir(scope.getName()), OmFileHelper.getName(streamName, EXTENSION_FLV)); - - IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils.getScopeService(scope, IStreamableFileFactory.class, - StreamableFileFactory.class); - - if (!file.isFile()) { - // Maybe the (previously existing) file has been deleted - file.createNewFile(); - - } else if (!file.canWrite()) { - throw new IOException("The file is read-only"); - } - - IStreamableFileService service = factory.getService(file); - IStreamableFile flv = service.getStreamableFile(file); - writer = flv.getWriter(); - } - - private void open() { - running = true; - new Thread(this, "Recording " + file.getName()).start(); - } - - public void stop() { - dostopping = true; - } - - @Override - public void run() { - log.debug("##REC:: stream writer started"); - long lastPackedRecieved = System.currentTimeMillis() + TIME_TO_WAIT_FOR_FRAME; - long counter = 0; - while (!stopping) { - try { - CachedEvent item = queue.poll(100, TimeUnit.MICROSECONDS); - if (item != null) { - log.trace("##REC:: got packet"); - lastPackedRecieved = System.currentTimeMillis(); - if (dostopping) { - log.trace("metadatId: {} :: Recording stopped but still packets to write to file!", metaDataId); - } - - packetReceived(item); - } else if (dostopping || lastPackedRecieved + TIME_TO_WAIT_FOR_FRAME < System.currentTimeMillis()) { - log.debug(String.format("##REC:: none packets received for: %s minutes, exiting", (System.currentTimeMillis() - lastPackedRecieved) / MINUTE_MULTIPLIER)); - stopping = true; - closeStream(); - } - if (++counter % 5000 == 0) { - log.debug("##REC:: Stream writer is still listening:: " + file.getName()); - } - } catch (InterruptedException e) { - log.error("##REC:: [run]", e); - } - } - log.debug("##REC:: stream writer stopped"); - } - - /** - * Write the actual packet data to the disk and do calculate any needed additional information - * - * @param streampacket - */ - public abstract void packetReceived(CachedEvent streampacket); - - protected abstract void internalCloseStream(); - /** - * called when the stream is finished written on the disk - */ - public void closeStream() { - try { - writer.close(); - } catch (Exception err) { - log.error("[closeStream, close writer]", err); - } - internalCloseStream(); - // Write the complete Bit to the meta data, the converter task will wait for this bit! - try { - RecordingMetaData metaData = metaDataDao.get(metaDataId); - log.debug("##REC:: Stream Status was: {} has been written for: {}", metaData.getStreamStatus(), metaDataId); - metaData.setStreamStatus(Status.STOPPED); - metaDataDao.update(metaData); - } catch (Exception err) { - log.error("##REC:: [closeStream, complete Bit]", err); - } - } - - public void append(CachedEvent streampacket) { - if (!running) { - throw new IllegalStateException("Append called before the Thread was started!"); - } - try { - queue.put(streampacket); - log.trace("##REC:: Q put, successful: " + queue.size()); - } catch (InterruptedException ignored) { - log.error("##REC:: [append]", ignored); - } - } - -} +/* + * 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.core.data.record.listener.async; + +import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV; +import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; + +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao; +import org.apache.openmeetings.db.entity.record.RecordingMetaData; +import org.apache.openmeetings.db.entity.record.RecordingMetaData.Status; +import org.apache.openmeetings.util.OmFileHelper; +import org.red5.io.IStreamableFile; +import org.red5.io.ITagWriter; +import org.red5.logging.Red5LoggerFactory; +import org.red5.server.api.scope.IScope; +import org.red5.server.api.service.IStreamableFileService; +import org.red5.server.api.stream.IStreamableFileFactory; +import org.red5.server.stream.StreamableFileFactory; +import org.red5.server.util.ScopeUtils; +import org.slf4j.Logger; + +public abstract class BaseStreamWriter implements Runnable { + private static final Logger log = Red5LoggerFactory.getLogger(BaseStreamWriter.class, webAppRootKey); + private final static int MINUTE_MULTIPLIER = 60 * 1000; + public final static int TIME_TO_WAIT_FOR_FRAME = 15 * MINUTE_MULTIPLIER; + protected int startTimeStamp = -1; + protected long initialDelta = 0; + + // thread is running + private boolean running = false; + // thread is stopped + private boolean stopping = false; + // thread will be stopped as soon as the queue is empty + private boolean dostopping = false; + + protected ITagWriter writer = null; + + protected Long metaDataId = null; + + protected Date startedSessionTimeDate = null; + + protected File file; + + protected IScope scope; + + protected boolean isScreenData = false; + + protected String streamName = ""; + protected final RecordingMetaDataDao metaDataDao; + private final BlockingQueue<CachedEvent> queue = new LinkedBlockingQueue<>(); + + public BaseStreamWriter(String streamName, IScope scope, Long metaDataId, boolean isScreenData, RecordingMetaDataDao metaDataDao) { + startedSessionTimeDate = new Date(); + this.isScreenData = isScreenData; + this.streamName = streamName; + this.metaDataId = metaDataId; + this.metaDataDao = metaDataDao; + this.scope = scope; + try { + init(); + } catch (IOException ex) { + log.error("##REC:: [BaseStreamWriter] Could not init Thread", ex); + } + RecordingMetaData metaData = metaDataDao.get(metaDataId); + metaData.setStreamStatus(Status.STARTED); + metaDataDao.update(metaData); + + open(); + } + + /** + * Initialization + * + * @throws IOException + * I/O exception + */ + private void init() throws IOException { + file = new File(OmFileHelper.getStreamsSubDir(scope.getName()), OmFileHelper.getName(streamName, EXTENSION_FLV)); + + IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils.getScopeService(scope, IStreamableFileFactory.class, + StreamableFileFactory.class); + + if (!file.isFile()) { + // Maybe the (previously existing) file has been deleted + file.createNewFile(); + + } else if (!file.canWrite()) { + throw new IOException("The file is read-only"); + } + + IStreamableFileService service = factory.getService(file); + IStreamableFile flv = service.getStreamableFile(file); + writer = flv.getWriter(); + } + + private void open() { + running = true; + new Thread(this, "Recording " + file.getName()).start(); + } + + public void stop() { + dostopping = true; + } + + @Override + public void run() { + log.debug("##REC:: stream writer started"); + long lastPackedRecieved = System.currentTimeMillis() + TIME_TO_WAIT_FOR_FRAME; + long counter = 0; + while (!stopping) { + try { + CachedEvent item = queue.poll(100, TimeUnit.MICROSECONDS); + if (item != null) { + log.trace("##REC:: got packet"); + lastPackedRecieved = System.currentTimeMillis(); + if (dostopping) { + log.trace("metadatId: {} :: Recording stopped but still packets to write to file!", metaDataId); + } + + packetReceived(item); + } else if (dostopping || lastPackedRecieved + TIME_TO_WAIT_FOR_FRAME < System.currentTimeMillis()) { + log.debug(String.format("##REC:: none packets received for: %s minutes, exiting", (System.currentTimeMillis() - lastPackedRecieved) / MINUTE_MULTIPLIER)); + stopping = true; + closeStream(); + } + if (++counter % 5000 == 0) { + log.debug("##REC:: Stream writer is still listening:: " + file.getName()); + } + } catch (InterruptedException e) { + log.error("##REC:: [run]", e); + } + } + log.debug("##REC:: stream writer stopped"); + } + + /** + * Write the actual packet data to the disk and do calculate any needed additional information + * + * @param streampacket + */ + public abstract void packetReceived(CachedEvent streampacket); + + protected abstract void internalCloseStream(); + /** + * called when the stream is finished written on the disk + */ + public void closeStream() { + try { + writer.close(); + } catch (Exception err) { + log.error("[closeStream, close writer]", err); + } + internalCloseStream(); + // Write the complete Bit to the meta data, the converter task will wait for this bit! + try { + RecordingMetaData metaData = metaDataDao.get(metaDataId); + log.debug("##REC:: Stream Status was: {} has been written for: {}", metaData.getStreamStatus(), metaDataId); + metaData.setStreamStatus(Status.STOPPED); + metaDataDao.update(metaData); + } catch (Exception err) { + log.error("##REC:: [closeStream, complete Bit]", err); + } + } + + public void append(CachedEvent streampacket) { + if (!running) { + throw new IllegalStateException("Append called before the Thread was started!"); + } + try { + queue.put(streampacket); + log.trace("##REC:: Q put, successful: " + queue.size()); + } catch (InterruptedException ignored) { + log.error("##REC:: [append]", ignored); + } + } + +} http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/CachedEvent.java ---------------------------------------------------------------------- diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/CachedEvent.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/CachedEvent.java index 433cf80..4184290 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/CachedEvent.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/CachedEvent.java @@ -1,76 +1,76 @@ -/* - * 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.core.data.record.listener.async; - -import java.util.Date; - -import org.apache.mina.core.buffer.IoBuffer; -import org.red5.server.api.stream.IStreamPacket; -import org.red5.server.net.rtmp.event.VideoData.FrameType; - -public class CachedEvent implements IStreamPacket { - private byte dataType; - private int timestamp; //this is the timeStamp, showing the time elapsed since the microphone was turned on - private IoBuffer data; - private Date currentTime; //this is the actually current timeStamp when the packet with audio data did enter the server - private FrameType frameType = FrameType.UNKNOWN; - - public Date getCurrentTime() { - return currentTime; - } - - public void setCurrentTime(Date currentTime) { - this.currentTime = currentTime; - } - - public void setDataType(byte dataType) { - this.dataType = dataType; - } - - public void setTimestamp(int timestamp) { - this.timestamp = timestamp; - } - - public void setData(IoBuffer data) { - this.data = data; - } - - @Override - public byte getDataType() { - return dataType; - } - - @Override - public int getTimestamp() { - return timestamp; - } - - @Override - public IoBuffer getData() { - return data; - } - - public FrameType getFrameType() { - return frameType; - } - - public void setFrameType(FrameType frameType) { - this.frameType = frameType; - } -} +/* + * 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.core.data.record.listener.async; + +import java.util.Date; + +import org.apache.mina.core.buffer.IoBuffer; +import org.red5.server.api.stream.IStreamPacket; +import org.red5.server.net.rtmp.event.VideoData.FrameType; + +public class CachedEvent implements IStreamPacket { + private byte dataType; + private int timestamp; //this is the timeStamp, showing the time elapsed since the microphone was turned on + private IoBuffer data; + private Date currentTime; //this is the actually current timeStamp when the packet with audio data did enter the server + private FrameType frameType = FrameType.UNKNOWN; + + public Date getCurrentTime() { + return currentTime; + } + + public void setCurrentTime(Date currentTime) { + this.currentTime = currentTime; + } + + public void setDataType(byte dataType) { + this.dataType = dataType; + } + + public void setTimestamp(int timestamp) { + this.timestamp = timestamp; + } + + public void setData(IoBuffer data) { + this.data = data; + } + + @Override + public byte getDataType() { + return dataType; + } + + @Override + public int getTimestamp() { + return timestamp; + } + + @Override + public IoBuffer getData() { + return data; + } + + public FrameType getFrameType() { + return frameType; + } + + public void setFrameType(FrameType frameType) { + this.frameType = frameType; + } +} http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamAudioWriter.java ---------------------------------------------------------------------- diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamAudioWriter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamAudioWriter.java index a7391a6..736fea6 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamAudioWriter.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamAudioWriter.java @@ -1,228 +1,228 @@ -/* - * 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.core.data.record.listener.async; - -import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; -import static org.red5.io.IoConstants.TYPE_AUDIO; -import static org.red5.server.net.rtmp.event.VideoData.FrameType.KEYFRAME; - -import java.util.Date; - -import org.apache.mina.core.buffer.IoBuffer; -import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao; -import org.apache.openmeetings.db.dao.record.RecordingMetaDeltaDao; -import org.apache.openmeetings.db.entity.record.RecordingMetaData; -import org.apache.openmeetings.db.entity.record.RecordingMetaDelta; -import org.red5.io.ITag; -import org.red5.io.flv.impl.Tag; -import org.red5.logging.Red5LoggerFactory; -import org.red5.server.api.scope.IScope; -import org.slf4j.Logger; - -public class StreamAudioWriter extends BaseStreamWriter { - private static final Logger log = Red5LoggerFactory.getLogger(StreamAudioWriter.class, webAppRootKey); - - private int duration = 0; - - private Integer lastTimeStamp = -1; - private Date lastcurrentTime = null; - - private int lastStreamPacketTimeStamp = -1; - - private long byteCount = 0; - - // Autowire is not possible - protected final RecordingMetaDeltaDao metaDeltaDao; - - private boolean isInterview = false; - - public StreamAudioWriter(String streamName, IScope scope, Long metaDataId, boolean isScreenData, - boolean isInterview, RecordingMetaDataDao metaDataDao, RecordingMetaDeltaDao metaDeltaDao) { - super(streamName, scope, metaDataId, isScreenData, metaDataDao); - - this.metaDeltaDao = metaDeltaDao; - this.isInterview = isInterview; - } - - @Override - public void packetReceived(CachedEvent streampacket) { - try { - // We only care about audio at this moment - if (isInterview || TYPE_AUDIO == streampacket.getDataType()) { - if (streampacket.getTimestamp() <= 0) { - log.warn("##REC:: Negative TimeStamp"); - return; - } - // we should not skip audio data in case it is Audio only interview - if (isInterview && isScreenData && startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) { - //skip until keyframe - log.trace("##REC:: no KEYFRAME, skipping"); - return; - } - IoBuffer data = streampacket.getData().asReadOnlyBuffer(); - if (data.limit() == 0) { - log.trace("##REC:: data.limit() == 0 "); - return; - } - - byteCount += data.limit(); - - lastcurrentTime = streampacket.getCurrentTime(); - int timeStamp = streampacket.getTimestamp(); - Date virtualTime = streampacket.getCurrentTime(); - - if (startTimeStamp == -1) { - // Calculate the delta between the initial start and the first audio-packet data - - initialDelta = virtualTime.getTime() - startedSessionTimeDate.getTime(); - - RecordingMetaDelta metaDelta = new RecordingMetaDelta(); - - metaDelta.setDeltaTime(initialDelta); - metaDelta.setMetaDataId(metaDataId); - metaDelta.setTimeStamp(0); - metaDelta.setDebugStatus("INIT AUDIO"); - metaDelta.setStartPadding(true); - metaDelta.setEndPadding(false); - metaDelta.setDataLengthPacket(data.limit()); - metaDelta.setReceivedAudioDataLength(byteCount); - metaDelta.setStartTime(startedSessionTimeDate); - metaDelta.setPacketTimeStamp(streampacket.getTimestamp()); - - Long deltaTimeStamp = virtualTime.getTime() - startedSessionTimeDate.getTime(); - - metaDelta.setDuration(0); - - Long missingTime = deltaTimeStamp - 0; - - metaDelta.setMissingTime(missingTime); - - metaDelta.setCurrentTime(virtualTime); - metaDelta.setDeltaTimeStamp(deltaTimeStamp); - metaDelta.setStartTimeStamp(startTimeStamp); - - metaDeltaDao.add(metaDelta); - - // That will be not bigger then long value - startTimeStamp = streampacket.getTimestamp(); - - RecordingMetaData metaData = metaDataDao.get(metaDataId); - metaData.setRecordStart(virtualTime); - metaDataDao.update(metaData); - } - - lastStreamPacketTimeStamp = streampacket.getTimestamp(); - - timeStamp -= startTimeStamp; - - // Offset at the beginning is calculated above - long deltaTime = lastTimeStamp == -1 ? 0 : timeStamp - lastTimeStamp; - - Long preLastTimeStamp = Long.parseLong(lastTimeStamp.toString()); - - lastTimeStamp = timeStamp; - - if (deltaTime > 75) { - RecordingMetaDelta metaDelta = new RecordingMetaDelta(); - - metaDelta.setDeltaTime(deltaTime); - metaDelta.setMetaDataId(metaDataId); - metaDelta.setTimeStamp(timeStamp); - metaDelta.setDebugStatus("RUN AUDIO"); - metaDelta.setStartPadding(false); - metaDelta.setLastTimeStamp(preLastTimeStamp); - metaDelta.setEndPadding(false); - metaDelta.setDataLengthPacket(data.limit()); - metaDelta.setReceivedAudioDataLength(byteCount); - metaDelta.setStartTime(startedSessionTimeDate); - metaDelta.setPacketTimeStamp(streampacket.getTimestamp()); - - Date current_date = new Date(); - Long deltaTimeStamp = current_date.getTime() - startedSessionTimeDate.getTime(); - - duration = Math.max(duration, timeStamp + writer.getOffset()); - metaDelta.setDuration(duration); - - Long missingTime = deltaTimeStamp - timeStamp; - - metaDelta.setMissingTime(missingTime); - - metaDelta.setCurrentTime(current_date); - metaDelta.setDeltaTimeStamp(deltaTimeStamp); - metaDelta.setStartTimeStamp(startTimeStamp); - - metaDeltaDao.add(metaDelta); - } - - log.trace("##REC:: timeStamp :: " + timeStamp); - ITag tag = new Tag(); - tag.setDataType(streampacket.getDataType()); - - // log.debug("data.limit() :: "+data.limit()); - tag.setBodySize(data.limit()); - tag.setTimestamp(timeStamp); - tag.setBody(data); - - writer.writeTag(tag); - - } - } catch (Exception e) { - log.error("##REC:: [packetReceived]", e); - } - } - - @Override - protected void internalCloseStream() { - try { - // We do not add any End Padding or count the gaps for the - // Screen Data, cause there is no! - - Date virtualTime = lastcurrentTime; - log.debug("##REC:: virtualTime: " + virtualTime); - log.debug("##REC:: startedSessionTimeDate: " + startedSessionTimeDate); - - long deltaRecordingTime = virtualTime == null ? 0 : virtualTime.getTime() - startedSessionTimeDate.getTime(); - - log.debug("##REC:: lastTimeStamp :closeStream: " + lastTimeStamp); - log.debug("##REC:: lastStreamPacketTimeStamp :closeStream: " + lastStreamPacketTimeStamp); - log.debug("##REC:: deltaRecordingTime :closeStream: " + deltaRecordingTime); - - long deltaTimePaddingEnd = deltaRecordingTime - lastTimeStamp - initialDelta; - - log.debug("##REC:: deltaTimePaddingEnd :: " + deltaTimePaddingEnd); - - RecordingMetaDelta metaDelta = new RecordingMetaDelta(); - - metaDelta.setDeltaTime(deltaTimePaddingEnd); - metaDelta.setMetaDataId(metaDataId); - metaDelta.setTimeStamp(lastTimeStamp); - metaDelta.setDebugStatus("END AUDIO"); - metaDelta.setStartPadding(false); - metaDelta.setEndPadding(true); - metaDelta.setDataLengthPacket(null); - metaDelta.setReceivedAudioDataLength(byteCount); - metaDelta.setStartTime(startedSessionTimeDate); - metaDelta.setCurrentTime(new Date()); - - metaDeltaDao.add(metaDelta); - } catch (Exception err) { - log.error("##REC:: [internalCloseStream]", err); - } - } -} +/* + * 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.core.data.record.listener.async; + +import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; +import static org.red5.io.IoConstants.TYPE_AUDIO; +import static org.red5.server.net.rtmp.event.VideoData.FrameType.KEYFRAME; + +import java.util.Date; + +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao; +import org.apache.openmeetings.db.dao.record.RecordingMetaDeltaDao; +import org.apache.openmeetings.db.entity.record.RecordingMetaData; +import org.apache.openmeetings.db.entity.record.RecordingMetaDelta; +import org.red5.io.ITag; +import org.red5.io.flv.impl.Tag; +import org.red5.logging.Red5LoggerFactory; +import org.red5.server.api.scope.IScope; +import org.slf4j.Logger; + +public class StreamAudioWriter extends BaseStreamWriter { + private static final Logger log = Red5LoggerFactory.getLogger(StreamAudioWriter.class, webAppRootKey); + + private int duration = 0; + + private Integer lastTimeStamp = -1; + private Date lastcurrentTime = null; + + private int lastStreamPacketTimeStamp = -1; + + private long byteCount = 0; + + // Autowire is not possible + protected final RecordingMetaDeltaDao metaDeltaDao; + + private boolean isInterview = false; + + public StreamAudioWriter(String streamName, IScope scope, Long metaDataId, boolean isScreenData, + boolean isInterview, RecordingMetaDataDao metaDataDao, RecordingMetaDeltaDao metaDeltaDao) { + super(streamName, scope, metaDataId, isScreenData, metaDataDao); + + this.metaDeltaDao = metaDeltaDao; + this.isInterview = isInterview; + } + + @Override + public void packetReceived(CachedEvent streampacket) { + try { + // We only care about audio at this moment + if (isInterview || TYPE_AUDIO == streampacket.getDataType()) { + if (streampacket.getTimestamp() <= 0) { + log.warn("##REC:: Negative TimeStamp"); + return; + } + // we should not skip audio data in case it is Audio only interview + if (isInterview && isScreenData && startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) { + //skip until keyframe + log.trace("##REC:: no KEYFRAME, skipping"); + return; + } + IoBuffer data = streampacket.getData().asReadOnlyBuffer(); + if (data.limit() == 0) { + log.trace("##REC:: data.limit() == 0 "); + return; + } + + byteCount += data.limit(); + + lastcurrentTime = streampacket.getCurrentTime(); + int timeStamp = streampacket.getTimestamp(); + Date virtualTime = streampacket.getCurrentTime(); + + if (startTimeStamp == -1) { + // Calculate the delta between the initial start and the first audio-packet data + + initialDelta = virtualTime.getTime() - startedSessionTimeDate.getTime(); + + RecordingMetaDelta metaDelta = new RecordingMetaDelta(); + + metaDelta.setDeltaTime(initialDelta); + metaDelta.setMetaDataId(metaDataId); + metaDelta.setTimeStamp(0); + metaDelta.setDebugStatus("INIT AUDIO"); + metaDelta.setStartPadding(true); + metaDelta.setEndPadding(false); + metaDelta.setDataLengthPacket(data.limit()); + metaDelta.setReceivedAudioDataLength(byteCount); + metaDelta.setStartTime(startedSessionTimeDate); + metaDelta.setPacketTimeStamp(streampacket.getTimestamp()); + + Long deltaTimeStamp = virtualTime.getTime() - startedSessionTimeDate.getTime(); + + metaDelta.setDuration(0); + + Long missingTime = deltaTimeStamp - 0; + + metaDelta.setMissingTime(missingTime); + + metaDelta.setCurrentTime(virtualTime); + metaDelta.setDeltaTimeStamp(deltaTimeStamp); + metaDelta.setStartTimeStamp(startTimeStamp); + + metaDeltaDao.add(metaDelta); + + // That will be not bigger then long value + startTimeStamp = streampacket.getTimestamp(); + + RecordingMetaData metaData = metaDataDao.get(metaDataId); + metaData.setRecordStart(virtualTime); + metaDataDao.update(metaData); + } + + lastStreamPacketTimeStamp = streampacket.getTimestamp(); + + timeStamp -= startTimeStamp; + + // Offset at the beginning is calculated above + long deltaTime = lastTimeStamp == -1 ? 0 : timeStamp - lastTimeStamp; + + Long preLastTimeStamp = Long.parseLong(lastTimeStamp.toString()); + + lastTimeStamp = timeStamp; + + if (deltaTime > 75) { + RecordingMetaDelta metaDelta = new RecordingMetaDelta(); + + metaDelta.setDeltaTime(deltaTime); + metaDelta.setMetaDataId(metaDataId); + metaDelta.setTimeStamp(timeStamp); + metaDelta.setDebugStatus("RUN AUDIO"); + metaDelta.setStartPadding(false); + metaDelta.setLastTimeStamp(preLastTimeStamp); + metaDelta.setEndPadding(false); + metaDelta.setDataLengthPacket(data.limit()); + metaDelta.setReceivedAudioDataLength(byteCount); + metaDelta.setStartTime(startedSessionTimeDate); + metaDelta.setPacketTimeStamp(streampacket.getTimestamp()); + + Date current_date = new Date(); + Long deltaTimeStamp = current_date.getTime() - startedSessionTimeDate.getTime(); + + duration = Math.max(duration, timeStamp + writer.getOffset()); + metaDelta.setDuration(duration); + + Long missingTime = deltaTimeStamp - timeStamp; + + metaDelta.setMissingTime(missingTime); + + metaDelta.setCurrentTime(current_date); + metaDelta.setDeltaTimeStamp(deltaTimeStamp); + metaDelta.setStartTimeStamp(startTimeStamp); + + metaDeltaDao.add(metaDelta); + } + + log.trace("##REC:: timeStamp :: " + timeStamp); + ITag tag = new Tag(); + tag.setDataType(streampacket.getDataType()); + + // log.debug("data.limit() :: "+data.limit()); + tag.setBodySize(data.limit()); + tag.setTimestamp(timeStamp); + tag.setBody(data); + + writer.writeTag(tag); + + } + } catch (Exception e) { + log.error("##REC:: [packetReceived]", e); + } + } + + @Override + protected void internalCloseStream() { + try { + // We do not add any End Padding or count the gaps for the + // Screen Data, cause there is no! + + Date virtualTime = lastcurrentTime; + log.debug("##REC:: virtualTime: " + virtualTime); + log.debug("##REC:: startedSessionTimeDate: " + startedSessionTimeDate); + + long deltaRecordingTime = virtualTime == null ? 0 : virtualTime.getTime() - startedSessionTimeDate.getTime(); + + log.debug("##REC:: lastTimeStamp :closeStream: " + lastTimeStamp); + log.debug("##REC:: lastStreamPacketTimeStamp :closeStream: " + lastStreamPacketTimeStamp); + log.debug("##REC:: deltaRecordingTime :closeStream: " + deltaRecordingTime); + + long deltaTimePaddingEnd = deltaRecordingTime - lastTimeStamp - initialDelta; + + log.debug("##REC:: deltaTimePaddingEnd :: " + deltaTimePaddingEnd); + + RecordingMetaDelta metaDelta = new RecordingMetaDelta(); + + metaDelta.setDeltaTime(deltaTimePaddingEnd); + metaDelta.setMetaDataId(metaDataId); + metaDelta.setTimeStamp(lastTimeStamp); + metaDelta.setDebugStatus("END AUDIO"); + metaDelta.setStartPadding(false); + metaDelta.setEndPadding(true); + metaDelta.setDataLengthPacket(null); + metaDelta.setReceivedAudioDataLength(byteCount); + metaDelta.setStartTime(startedSessionTimeDate); + metaDelta.setCurrentTime(new Date()); + + metaDeltaDao.add(metaDelta); + } catch (Exception err) { + log.error("##REC:: [internalCloseStream]", err); + } + } +} http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamVideoWriter.java ---------------------------------------------------------------------- diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamVideoWriter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamVideoWriter.java index 169379d..8596042 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamVideoWriter.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/record/listener/async/StreamVideoWriter.java @@ -1,98 +1,98 @@ -/* - * 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.core.data.record.listener.async; - -import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; -import static org.red5.server.net.rtmp.event.VideoData.FrameType.KEYFRAME; - -import java.util.Date; - -import org.apache.mina.core.buffer.IoBuffer; -import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao; -import org.apache.openmeetings.db.entity.record.RecordingMetaData; -import org.red5.io.ITag; -import org.red5.io.flv.impl.Tag; -import org.red5.logging.Red5LoggerFactory; -import org.red5.server.api.scope.IScope; -import org.slf4j.Logger; - -public class StreamVideoWriter extends BaseStreamWriter { - private static final Logger log = Red5LoggerFactory.getLogger(StreamVideoWriter.class, webAppRootKey); - private Date startedSessionScreenTimeDate = null; - - public StreamVideoWriter(String streamName, IScope scope, Long metaDataId, boolean isScreenData, - RecordingMetaDataDao metaDataDao) { - - super(streamName, scope, metaDataId, isScreenData, metaDataDao); - } - - @Override - public void packetReceived(CachedEvent streampacket) { - try { - int timeStamp = streampacket.getTimestamp(); - log.trace("incoming timeStamp :: " + timeStamp); - if (startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) { - //skip until keyframe - log.trace("no KEYFRAME, skipping ::" + streampacket.getFrameType()); - return; - } - if (timeStamp <= 0) { - log.warn("Negative TimeStamp"); - return; - } - IoBuffer data = streampacket.getData().asReadOnlyBuffer(); - if (data.limit() == 0) { - log.trace("Data.limit() == 0"); - return; - } - Date virtualTime = streampacket.getCurrentTime(); - - if (startedSessionScreenTimeDate == null) { - startedSessionScreenTimeDate = virtualTime; - - RecordingMetaData metaData = metaDataDao.get(metaDataId); - metaData.setRecordStart(virtualTime); - metaDataDao.update(metaData); - } - - if (startTimeStamp == -1) { - // That will be not bigger then long value - startTimeStamp = timeStamp; - } - - timeStamp -= startTimeStamp; - - log.trace("timeStamp :: " + timeStamp); - ITag tag = new Tag(); - tag.setDataType(streampacket.getDataType()); - - tag.setBodySize(data.limit()); - tag.setTimestamp(timeStamp); - tag.setBody(data); - - writer.writeTag(tag); - } catch (Exception e) { - log.error("[packetReceived]", e); - } - } - - @Override - protected void internalCloseStream() { - } -} +/* + * 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.core.data.record.listener.async; + +import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; +import static org.red5.server.net.rtmp.event.VideoData.FrameType.KEYFRAME; + +import java.util.Date; + +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao; +import org.apache.openmeetings.db.entity.record.RecordingMetaData; +import org.red5.io.ITag; +import org.red5.io.flv.impl.Tag; +import org.red5.logging.Red5LoggerFactory; +import org.red5.server.api.scope.IScope; +import org.slf4j.Logger; + +public class StreamVideoWriter extends BaseStreamWriter { + private static final Logger log = Red5LoggerFactory.getLogger(StreamVideoWriter.class, webAppRootKey); + private Date startedSessionScreenTimeDate = null; + + public StreamVideoWriter(String streamName, IScope scope, Long metaDataId, boolean isScreenData, + RecordingMetaDataDao metaDataDao) { + + super(streamName, scope, metaDataId, isScreenData, metaDataDao); + } + + @Override + public void packetReceived(CachedEvent streampacket) { + try { + int timeStamp = streampacket.getTimestamp(); + log.trace("incoming timeStamp :: " + timeStamp); + if (startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) { + //skip until keyframe + log.trace("no KEYFRAME, skipping ::" + streampacket.getFrameType()); + return; + } + if (timeStamp <= 0) { + log.warn("Negative TimeStamp"); + return; + } + IoBuffer data = streampacket.getData().asReadOnlyBuffer(); + if (data.limit() == 0) { + log.trace("Data.limit() == 0"); + return; + } + Date virtualTime = streampacket.getCurrentTime(); + + if (startedSessionScreenTimeDate == null) { + startedSessionScreenTimeDate = virtualTime; + + RecordingMetaData metaData = metaDataDao.get(metaDataId); + metaData.setRecordStart(virtualTime); + metaDataDao.update(metaData); + } + + if (startTimeStamp == -1) { + // That will be not bigger then long value + startTimeStamp = timeStamp; + } + + timeStamp -= startTimeStamp; + + log.trace("timeStamp :: " + timeStamp); + ITag tag = new Tag(); + tag.setDataType(streampacket.getDataType()); + + tag.setBodySize(data.limit()); + tag.setTimestamp(timeStamp); + tag.setBody(data); + + writer.writeTag(tag); + } catch (Exception e) { + log.error("[packetReceived]", e); + } + } + + @Override + protected void internalCloseStream() { + } +} http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8e63647c/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/SMSHandler.java ---------------------------------------------------------------------- diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/SMSHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/SMSHandler.java index 89d62b4..bf17d61 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/SMSHandler.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/SMSHandler.java @@ -1,118 +1,118 @@ -/* - * 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.core.mail; - -import org.apache.openmeetings.db.dao.basic.ConfigurationDao; -import org.apache.openmeetings.util.OpenmeetingsVariables; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import org.smslib.Message.MessageEncodings; -import org.smslib.OutboundMessage; -import org.smslib.Service; -import org.smslib.http.BulkSmsHTTPGateway; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.task.TaskExecutor; - -/** - * - * @author iarkh - * - */ - -public class SMSHandler { - - private static final Logger log = Red5LoggerFactory.getLogger( - SMSHandler.class, OpenmeetingsVariables.webAppRootKey); - - @Autowired - protected ConfigurationDao configurationDao; - @Autowired - protected TaskExecutor taskExecutor; - - private BulkSmsHTTPGateway gateway = null; - - private boolean checkBalance() throws Exception { - if (gateway == null) { - String smsProvider = configurationDao.getConfValue("sms.provider", String.class, null); - String smsUsername = configurationDao.getConfValue("sms.username", String.class, null); - String smsUserpass = configurationDao.getConfValue("sms.userpass", String.class, null); - - if (smsProvider == null || smsProvider.length() == 0 || - smsUsername == null || smsUsername.length() == 0) { - log.error("SMS Provider is not configured properly!"); - return false; - } - gateway = new BulkSmsHTTPGateway(smsProvider, smsUsername, smsUserpass); - gateway.setOutbound(true); - Service.getInstance().addGateway(gateway); - Service.getInstance().startService(); - } - return gateway.queryBalance() >= 1; - } - - public boolean sendSMS(String phone, String subj, long languageId) { - try { - taskExecutor.execute(new SMSSenderTask(phone, subj, languageId)); - return true; - } catch (Exception ex) { - log.error("sendSMS", ex); - return false; - } - } - - protected class SMSSenderTask implements Runnable { - private final String phone; - private final String subject; - private long languageId; - - public SMSSenderTask(String phone, String subject, long languageId) { - this.phone = phone; - this.subject = subject; - this.languageId = languageId; - } - - @Override - public void run() { - this.send(); - } - - /** - * Sending an SMS with the given values. - * @return <code>true</code> if sms was sent successfully, <code>false</code> otherwise. - */ - public boolean send() { - try { - log.debug("SMS sending to: " + phone + ", subject is: " + subject); - if (checkBalance()) { - OutboundMessage msg = new OutboundMessage(phone, subject); - if (languageId != 1) { - msg.setEncoding(MessageEncodings.ENCUCS2); - } - return Service.getInstance().sendMessage(msg); - } else { - log.error("Error: insufficient funds on SMS provider account!"); - return false; - } - } catch (Exception ex) { - log.error("Error sending sms: ", ex); - return false; - } - } - } -} +/* + * 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.core.mail; + +import org.apache.openmeetings.db.dao.basic.ConfigurationDao; +import org.apache.openmeetings.util.OpenmeetingsVariables; +import org.red5.logging.Red5LoggerFactory; +import org.slf4j.Logger; +import org.smslib.Message.MessageEncodings; +import org.smslib.OutboundMessage; +import org.smslib.Service; +import org.smslib.http.BulkSmsHTTPGateway; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.task.TaskExecutor; + +/** + * + * @author iarkh + * + */ + +public class SMSHandler { + + private static final Logger log = Red5LoggerFactory.getLogger( + SMSHandler.class, OpenmeetingsVariables.webAppRootKey); + + @Autowired + protected ConfigurationDao configurationDao; + @Autowired + protected TaskExecutor taskExecutor; + + private BulkSmsHTTPGateway gateway = null; + + private boolean checkBalance() throws Exception { + if (gateway == null) { + String smsProvider = configurationDao.getConfValue("sms.provider", String.class, null); + String smsUsername = configurationDao.getConfValue("sms.username", String.class, null); + String smsUserpass = configurationDao.getConfValue("sms.userpass", String.class, null); + + if (smsProvider == null || smsProvider.length() == 0 || + smsUsername == null || smsUsername.length() == 0) { + log.error("SMS Provider is not configured properly!"); + return false; + } + gateway = new BulkSmsHTTPGateway(smsProvider, smsUsername, smsUserpass); + gateway.setOutbound(true); + Service.getInstance().addGateway(gateway); + Service.getInstance().startService(); + } + return gateway.queryBalance() >= 1; + } + + public boolean sendSMS(String phone, String subj, long languageId) { + try { + taskExecutor.execute(new SMSSenderTask(phone, subj, languageId)); + return true; + } catch (Exception ex) { + log.error("sendSMS", ex); + return false; + } + } + + protected class SMSSenderTask implements Runnable { + private final String phone; + private final String subject; + private long languageId; + + public SMSSenderTask(String phone, String subject, long languageId) { + this.phone = phone; + this.subject = subject; + this.languageId = languageId; + } + + @Override + public void run() { + this.send(); + } + + /** + * Sending an SMS with the given values. + * @return <code>true</code> if sms was sent successfully, <code>false</code> otherwise. + */ + public boolean send() { + try { + log.debug("SMS sending to: " + phone + ", subject is: " + subject); + if (checkBalance()) { + OutboundMessage msg = new OutboundMessage(phone, subject); + if (languageId != 1) { + msg.setEncoding(MessageEncodings.ENCUCS2); + } + return Service.getInstance().sendMessage(msg); + } else { + log.error("Error: insufficient funds on SMS provider account!"); + return false; + } + } catch (Exception ex) { + log.error("Error sending sms: ", ex); + return false; + } + } + } +}
